<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Cache-Control" content="no-siteapp" />

    <title>Api Manual</title>
    <meta name="description" content="  Specification          Naming conventions      Note: This documents is only a mirror, if you want to see newest documents please goto: http://xmake.io/#/ma...">

    
    <meta name="keywords" content="xmake,docs,manual,tboox" /> 

    <!-- qq oauth -->
    <meta property="qc:admins" content="5211601217706727767255" />

    <!--icon -->
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" sizes="192x192" href="/static/img/nice-highres.png" />
	<link rel="apple-touch-icon-precomposed" href="/static/img/apple-touch-icon-57x57-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/static/img/apple-touch-icon-72x72-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/static/img/apple-touch-icon-114x114-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/static/img/apple-touch-icon-144x144-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="180x180" href="/static/img/retinahd_icon.png" />
	<meta name="msapplication-TileImage" content="/static/img/retinahd_icon.png" />
	
    <link rel="stylesheet" href=" /css/fontawesome/css/font-awesome.min.css ">
    <link rel="stylesheet" href=" /css/main.css ">
    <link rel="canonical" href="https://tboox.org/docs/xmake/manual/">
    <link rel="alternate" type="application/rss+xml" title="TBOOX Open Source Project" href="https://tboox.org/feed.xml ">
    <link rel="alternate" hreflang="en" href="https://tboox.org/" />
    <link rel="alternate" hreflang="zh-Hans" href="https://tboox.org/cn/" />




    <script type="text/javascript">
    function isPC(){    
        var userAgentInfo = navigator.userAgent;  
        var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");    
        var flag = true;    
        for (var v = 0; v < Agents.length; v++) {    
            if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }    
        }    
        return flag;    
    }
    </script>

<!-- baidu ads -->



    <!-- baidu ads -->

</head>


  <body>

    <header id="top">
    <div class="wrapper">
        <a href="/" class="brand">TBOOX</a>
        <button id="headerMenu" class="menu"><i class="fa fa-bars"></i></button>
        <nav id="headerNav">
            <ul>
                <li>
                    
                    <a href="/cn?lang=0">
                    
                        <i class="fa fa-home"></i>中文
                    </a>
                </li>

                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/project/">
                            
                        
                            <i class="fa fa-bookmark"></i>Projects
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/archive/">
                            
                        
                            <i class="fa fa-archive"></i>Archives
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/category/">
                            
                        
                            <i class="fa fa-th-list"></i>Categories
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/tag/">
                            
                        
                            <i class="fa fa-tags"></i>Tags
                        </a>
                    </li>
                    
                    
                    
                
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/docs/">
                            
                        
                            <i class="fa fa-book"></i>Documents
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="https://xmake.io/#/about/contact" target="_blank" >
                            
                        
                            <i class="fa fa-forumbee"></i>Community
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/donation/">
                            
                        
                            <i class="fa fa-heart"></i>Donate
                        </a>
                    </li>
                    
                    
                    
                
                    
                     
                    
                
                    
                     
                     
                    <li>

                        
                            
                            <a href="/about/">
                            
                        
                            <i class="fa fa-user"></i>About
                        </a>
                    </li>
                    
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                     
                     
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            </ul>
        </nav>
    </div>
</header>



        <div class="page clearfix" post>
    <div class="left">
        <h1>Api Manual</h1>
        <div class="label">

            <div class="label-card">
                <i class="fa fa-calendar"></i>2000-02-22
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
            


<!-- <span class="point">•</span> -->
<span class="categories">
  <i class="fa fa-th-list"></i>
  
    
        <a href="/category/#xmake" title="Category: xmake" rel="category">xmake</a>
    
  

  <!-- <span class="point">•</span> -->
</span>


            </div>

            <div class="label-card">
            
<!-- <span class="point">•</span> -->
<span class="pageTag">
  <i class="fa fa-tags"></i>
  
    
        <!--a href="/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a-->
        <a href="/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a>&nbsp;
    
        <!--a href="/tag/#docs" title="Tag: docs" rel="tag">docs</a-->
        <a href="/tag/#docs" title="Tag: docs" rel="tag">docs</a>&nbsp;
    
        <!--a href="/tag/#manual" title="Tag: manual" rel="tag">manual</a-->
        <a href="/tag/#manual" title="Tag: manual" rel="tag">manual</a>
    
  

</span>

            </div>

        </div>
        <hr>
        <article itemscope itemtype="http://schema.org/BlogPosting">
        <ul id="markdown-toc">
  <li><a href="#specification" id="markdown-toc-specification">Specification</a>    <ul>
      <li><a href="#naming-conventions" id="markdown-toc-naming-conventions">Naming conventions</a></li>
    </ul>
  </li>
  <li><a href="#documentation" id="markdown-toc-documentation">Documentation</a>    <ul>
      <li><a href="#conditions" id="markdown-toc-conditions">Conditions</a>        <ul>
          <li><a href="#is_os" id="markdown-toc-is_os">is_os</a>            <ul>
              <li><a href="#is-the-current-compilation-target-system" id="markdown-toc-is-the-current-compilation-target-system">Is the current compilation target system</a></li>
            </ul>
          </li>
          <li><a href="#is_arch" id="markdown-toc-is_arch">is_arch</a>            <ul>
              <li><a href="#is-the-current-compilation-architecture" id="markdown-toc-is-the-current-compilation-architecture">Is the current compilation architecture</a></li>
            </ul>
          </li>
          <li><a href="#is_plat" id="markdown-toc-is_plat">is_plat</a>            <ul>
              <li><a href="#is-the-current-compilation-platform" id="markdown-toc-is-the-current-compilation-platform">Is the current compilation platform</a></li>
            </ul>
          </li>
          <li><a href="#is_host" id="markdown-toc-is_host">is_host</a>            <ul>
              <li><a href="#is-the-current-compilation-host-system" id="markdown-toc-is-the-current-compilation-host-system">Is the current compilation host system</a></li>
            </ul>
          </li>
          <li><a href="#is_mode" id="markdown-toc-is_mode">is_mode</a>            <ul>
              <li><a href="#is-the-current-compilation-mode" id="markdown-toc-is-the-current-compilation-mode">Is the current compilation mode</a></li>
            </ul>
          </li>
          <li><a href="#is_kind" id="markdown-toc-is_kind">is_kind</a>            <ul>
              <li><a href="#is-the-current-target-kind" id="markdown-toc-is-the-current-target-kind">Is the current target kind</a></li>
            </ul>
          </li>
          <li><a href="#is_option" id="markdown-toc-is_option">is_option</a>            <ul>
              <li><a href="#is-the-given-options-enabled" id="markdown-toc-is-the-given-options-enabled">Is the given options enabled</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#global-interfaces" id="markdown-toc-global-interfaces">Global Interfaces</a>        <ul>
          <li><a href="#includes" id="markdown-toc-includes">includes</a>            <ul>
              <li><a href="#add-sub-project-files-and-directories" id="markdown-toc-add-sub-project-files-and-directories">Add sub-project files and directories</a></li>
            </ul>
          </li>
          <li><a href="#set_modes" id="markdown-toc-set_modes">set_modes</a>            <ul>
              <li><a href="#set-project-compilation-modes" id="markdown-toc-set-project-compilation-modes">Set project compilation modes</a></li>
            </ul>
          </li>
          <li><a href="#set_project" id="markdown-toc-set_project">set_project</a>            <ul>
              <li><a href="#set-project-name" id="markdown-toc-set-project-name">Set project name</a></li>
            </ul>
          </li>
          <li><a href="#set_version" id="markdown-toc-set_version">set_version</a>            <ul>
              <li><a href="#set-project-version" id="markdown-toc-set-project-version">Set project version</a></li>
            </ul>
          </li>
          <li><a href="#set_xmakever" id="markdown-toc-set_xmakever">set_xmakever</a>            <ul>
              <li><a href="#set-minimal-xmake-version" id="markdown-toc-set-minimal-xmake-version">Set minimal xmake version</a></li>
            </ul>
          </li>
          <li><a href="#add_subdirs" id="markdown-toc-add_subdirs">add_subdirs</a>            <ul>
              <li><a href="#add-sub-project-directories" id="markdown-toc-add-sub-project-directories">Add sub-project directories</a></li>
            </ul>
          </li>
          <li><a href="#add_subfiles" id="markdown-toc-add_subfiles">add_subfiles</a>            <ul>
              <li><a href="#add-sub-project-files" id="markdown-toc-add-sub-project-files">Add sub-project files</a></li>
            </ul>
          </li>
          <li><a href="#add_moduledirs" id="markdown-toc-add_moduledirs">add_moduledirs</a>            <ul>
              <li><a href="#add-module-directories" id="markdown-toc-add-module-directories">Add module directories</a></li>
            </ul>
          </li>
          <li><a href="#add_plugindirs" id="markdown-toc-add_plugindirs">add_plugindirs</a>            <ul>
              <li><a href="#add-plugin-directories" id="markdown-toc-add-plugin-directories">Add plugin directories</a></li>
            </ul>
          </li>
          <li><a href="#add_packagedirs" id="markdown-toc-add_packagedirs">add_packagedirs</a>            <ul>
              <li><a href="#add-package-directories" id="markdown-toc-add-package-directories">Add package directories</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#project-target" id="markdown-toc-project-target">Project Target</a>        <ul>
          <li><a href="#target" id="markdown-toc-target">target</a>            <ul>
              <li><a href="#define-a-project-target" id="markdown-toc-define-a-project-target">Define a project target</a></li>
            </ul>
          </li>
          <li><a href="#target_end" id="markdown-toc-target_end">target_end</a>            <ul>
              <li><a href="#end-target-definition" id="markdown-toc-end-target-definition">End target definition</a></li>
            </ul>
          </li>
          <li><a href="#targetset_kind" id="markdown-toc-targetset_kind">target:set_kind</a>            <ul>
              <li><a href="#set-target-kind" id="markdown-toc-set-target-kind">Set target kind</a></li>
            </ul>
          </li>
          <li><a href="#targetset_strip" id="markdown-toc-targetset_strip">target:set_strip</a>            <ul>
              <li><a href="#strip-target-symbols" id="markdown-toc-strip-target-symbols">Strip target symbols</a></li>
            </ul>
          </li>
          <li><a href="#targetset_default" id="markdown-toc-targetset_default">target:set_default</a>            <ul>
              <li><a href="#mark-as-default-target" id="markdown-toc-mark-as-default-target">Mark as default target</a></li>
            </ul>
          </li>
          <li><a href="#targetset_options" id="markdown-toc-targetset_options">target:set_options</a>            <ul>
              <li><a href="#set-configuartion-options" id="markdown-toc-set-configuartion-options">Set configuartion options</a></li>
            </ul>
          </li>
          <li><a href="#targetset_symbols" id="markdown-toc-targetset_symbols">target:set_symbols</a>            <ul>
              <li><a href="#set-symbol-info" id="markdown-toc-set-symbol-info">Set symbol info</a></li>
            </ul>
          </li>
          <li><a href="#targetset_basename" id="markdown-toc-targetset_basename">target:set_basename</a>            <ul>
              <li><a href="#set-the-base-name-for-target-file" id="markdown-toc-set-the-base-name-for-target-file">Set the base name for target file</a></li>
            </ul>
          </li>
          <li><a href="#targetset_warnings" id="markdown-toc-targetset_warnings">target:set_warnings</a>            <ul>
              <li><a href="#set-compilation-warning-level" id="markdown-toc-set-compilation-warning-level">Set compilation warning level</a></li>
            </ul>
          </li>
          <li><a href="#targetset_optimize" id="markdown-toc-targetset_optimize">target:set_optimize</a>            <ul>
              <li><a href="#set-compilation-optimization-level" id="markdown-toc-set-compilation-optimization-level">Set compilation optimization level</a></li>
            </ul>
          </li>
          <li><a href="#targetset_languages" id="markdown-toc-targetset_languages">target:set_languages</a>            <ul>
              <li><a href="#set-source-code-language-standards" id="markdown-toc-set-source-code-language-standards">Set source code language standards</a></li>
            </ul>
          </li>
          <li><a href="#targetset_headerdir" id="markdown-toc-targetset_headerdir">target:set_headerdir</a>            <ul>
              <li><a href="#set-output-directories-for-header-files" id="markdown-toc-set-output-directories-for-header-files">Set output directories for header files</a></li>
            </ul>
          </li>
          <li><a href="#targetset_targetdir" id="markdown-toc-targetset_targetdir">target:set_targetdir</a>            <ul>
              <li><a href="#set-output-directories-for-target-files" id="markdown-toc-set-output-directories-for-target-files">Set output directories for target files</a></li>
            </ul>
          </li>
          <li><a href="#targetset_objectdir" id="markdown-toc-targetset_objectdir">target:set_objectdir</a>            <ul>
              <li><a href="#set-output-directories-for-object-files" id="markdown-toc-set-output-directories-for-object-files">Set output directories for object files</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_imports" id="markdown-toc-targetadd_imports">target:add_imports</a>            <ul>
              <li><a href="#add-imported-modules-for-the-custom-script" id="markdown-toc-add-imported-modules-for-the-custom-script">Add imported modules for the custom script</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_rules" id="markdown-toc-targetadd_rules">target:add_rules</a>            <ul>
              <li><a href="#add-custom-compilation-rule-to-target" id="markdown-toc-add-custom-compilation-rule-to-target">Add custom compilation rule to target</a></li>
            </ul>
          </li>
          <li><a href="#targeton_load" id="markdown-toc-targeton_load">target:on_load</a>            <ul>
              <li><a href="#run-custom-load-target-configuartion-script" id="markdown-toc-run-custom-load-target-configuartion-script">Run custom load target configuartion script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_build" id="markdown-toc-targeton_build">target:on_build</a>            <ul>
              <li><a href="#run-custom-build-target-script" id="markdown-toc-run-custom-build-target-script">Run custom build target script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_clean" id="markdown-toc-targeton_clean">target:on_clean</a>            <ul>
              <li><a href="#run-custom-clean-files-script" id="markdown-toc-run-custom-clean-files-script">Run custom clean files script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_package" id="markdown-toc-targeton_package">target:on_package</a>            <ul>
              <li><a href="#run-custom-package-target-script" id="markdown-toc-run-custom-package-target-script">Run custom package target script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_install" id="markdown-toc-targeton_install">target:on_install</a>            <ul>
              <li><a href="#run-custom-install-target-file-script" id="markdown-toc-run-custom-install-target-file-script">Run custom install target file script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_uninstall" id="markdown-toc-targeton_uninstall">target:on_uninstall</a>            <ul>
              <li><a href="#run-custom-uninstall-target-file-script" id="markdown-toc-run-custom-uninstall-target-file-script">Run custom uninstall target file script</a></li>
            </ul>
          </li>
          <li><a href="#targeton_run" id="markdown-toc-targeton_run">target:on_run</a>            <ul>
              <li><a href="#run-custom-run-target-script" id="markdown-toc-run-custom-run-target-script">Run custom run target script</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_build" id="markdown-toc-targetbefore_build">target:before_build</a>            <ul>
              <li><a href="#run-custom-script-before-building-target" id="markdown-toc-run-custom-script-before-building-target">Run custom script before building target</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_clean" id="markdown-toc-targetbefore_clean">target:before_clean</a>            <ul>
              <li><a href="#run-custom-script-before-cleaning-target" id="markdown-toc-run-custom-script-before-cleaning-target">Run custom script before cleaning target</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_package" id="markdown-toc-targetbefore_package">target:before_package</a>            <ul>
              <li><a href="#run-custom-script-before-packaging-target" id="markdown-toc-run-custom-script-before-packaging-target">Run custom script before packaging target</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_install" id="markdown-toc-targetbefore_install">target:before_install</a>            <ul>
              <li><a href="#run-custom-script-before-installing-target" id="markdown-toc-run-custom-script-before-installing-target">Run custom script before installing target</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_uninstall" id="markdown-toc-targetbefore_uninstall">target:before_uninstall</a>            <ul>
              <li><a href="#run-custom-script-before-uninstalling-target" id="markdown-toc-run-custom-script-before-uninstalling-target">Run custom script before uninstalling target</a></li>
            </ul>
          </li>
          <li><a href="#targetbefore_run" id="markdown-toc-targetbefore_run">target:before_run</a>            <ul>
              <li><a href="#run-custom-script-before-running-target" id="markdown-toc-run-custom-script-before-running-target">Run custom script before running target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_build" id="markdown-toc-targetafter_build">target:after_build</a>            <ul>
              <li><a href="#run-custom-script-after-building-target" id="markdown-toc-run-custom-script-after-building-target">Run custom script after building target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_clean" id="markdown-toc-targetafter_clean">target:after_clean</a>            <ul>
              <li><a href="#run-custom-script-after-cleaning-target" id="markdown-toc-run-custom-script-after-cleaning-target">Run custom script after cleaning target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_package" id="markdown-toc-targetafter_package">target:after_package</a>            <ul>
              <li><a href="#run-custom-script-after-packaging-target" id="markdown-toc-run-custom-script-after-packaging-target">Run custom script after packaging target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_install" id="markdown-toc-targetafter_install">target:after_install</a>            <ul>
              <li><a href="#run-custom-script-after-installing-target" id="markdown-toc-run-custom-script-after-installing-target">Run custom script after installing target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_uninstall" id="markdown-toc-targetafter_uninstall">target:after_uninstall</a>            <ul>
              <li><a href="#run-custom-script-after-uninstalling-target" id="markdown-toc-run-custom-script-after-uninstalling-target">Run custom script after uninstalling target</a></li>
            </ul>
          </li>
          <li><a href="#targetafter_run" id="markdown-toc-targetafter_run">target:after_run</a>            <ul>
              <li><a href="#run-custom-script-after-running-target" id="markdown-toc-run-custom-script-after-running-target">Run custom script after running target</a></li>
            </ul>
          </li>
          <li><a href="#targetset_config_h" id="markdown-toc-targetset_config_h">target:set_config_h</a>            <ul>
              <li><a href="#set-auto-generated-config-header-file" id="markdown-toc-set-auto-generated-config-header-file">Set auto-generated config header file</a></li>
            </ul>
          </li>
          <li><a href="#targetset_config_h_prefix" id="markdown-toc-targetset_config_h_prefix">target:set_config_h_prefix</a>            <ul>
              <li><a href="#set-macro-prefix-in-auto-generated-config-header" id="markdown-toc-set-macro-prefix-in-auto-generated-config-header">Set macro prefix in auto-generated config header</a></li>
            </ul>
          </li>
          <li><a href="#targetset_config_header" id="markdown-toc-targetset_config_header">target:set_config_header</a>            <ul>
              <li><a href="#set-auto-generated-config-header-file-new" id="markdown-toc-set-auto-generated-config-header-file-new">Set auto-generated config header file (new)</a></li>
            </ul>
          </li>
          <li><a href="#targetset_pcheader" id="markdown-toc-targetset_pcheader">target:set_pcheader</a>            <ul>
              <li><a href="#set-pre-compiled-c-header-file" id="markdown-toc-set-pre-compiled-c-header-file">Set pre-compiled c header file</a></li>
            </ul>
          </li>
          <li><a href="#targetset_pcxxheader" id="markdown-toc-targetset_pcxxheader">target:set_pcxxheader</a>            <ul>
              <li><a href="#set-pre-compiled-c-header-file-1" id="markdown-toc-set-pre-compiled-c-header-file-1">Set pre-compiled c++ header file</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_deps" id="markdown-toc-targetadd_deps">target:add_deps</a>            <ul>
              <li><a href="#add-target-dependencies" id="markdown-toc-add-target-dependencies">Add target dependencies</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_links" id="markdown-toc-targetadd_links">target:add_links</a>            <ul>
              <li><a href="#add-link-libraries" id="markdown-toc-add-link-libraries">Add link libraries</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_files" id="markdown-toc-targetadd_files">target:add_files</a>            <ul>
              <li><a href="#add-source-files" id="markdown-toc-add-source-files">Add source files</a></li>
            </ul>
          </li>
          <li><a href="#targetdel_files" id="markdown-toc-targetdel_files">target:del_files</a>            <ul>
              <li><a href="#remove-source-files" id="markdown-toc-remove-source-files">Remove source files</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_headers" id="markdown-toc-targetadd_headers">target:add_headers</a>            <ul>
              <li><a href="#add-installed-header-files" id="markdown-toc-add-installed-header-files">Add installed header files</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_linkdirs" id="markdown-toc-targetadd_linkdirs">target:add_linkdirs</a>            <ul>
              <li><a href="#add-link-search-directories" id="markdown-toc-add-link-search-directories">Add link search directories</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_rpathdirs" id="markdown-toc-targetadd_rpathdirs">target:add_rpathdirs</a>            <ul>
              <li><a href="#add-load-search-directories-for-dynamic-libraries" id="markdown-toc-add-load-search-directories-for-dynamic-libraries">Add load search directories for dynamic libraries</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_includedirs" id="markdown-toc-targetadd_includedirs">target:add_includedirs</a>            <ul>
              <li><a href="#add-include-search-directories" id="markdown-toc-add-include-search-directories">Add include search directories</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_defines" id="markdown-toc-targetadd_defines">target:add_defines</a>            <ul>
              <li><a href="#add-macro-definition" id="markdown-toc-add-macro-definition">Add macro definition</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_undefines" id="markdown-toc-targetadd_undefines">target:add_undefines</a>            <ul>
              <li><a href="#add-macro-undefinition" id="markdown-toc-add-macro-undefinition">Add macro undefinition</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_defines_h" id="markdown-toc-targetadd_defines_h">target:add_defines_h</a>            <ul>
              <li><a href="#add-macro-definition-to-auto-generated-config-header" id="markdown-toc-add-macro-definition-to-auto-generated-config-header">Add macro definition to auto-generated config header</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_undefines_h" id="markdown-toc-targetadd_undefines_h">target:add_undefines_h</a>            <ul>
              <li><a href="#add-macro-undefinition-to-auto-generated-config-header" id="markdown-toc-add-macro-undefinition-to-auto-generated-config-header">Add macro undefinition to auto-generated config header</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cflags" id="markdown-toc-targetadd_cflags">target:add_cflags</a>            <ul>
              <li><a href="#add-c-compilation-flags" id="markdown-toc-add-c-compilation-flags">Add c compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cxflags" id="markdown-toc-targetadd_cxflags">target:add_cxflags</a>            <ul>
              <li><a href="#add-cc-compilation-flags" id="markdown-toc-add-cc-compilation-flags">Add c/c++ compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cxxflags" id="markdown-toc-targetadd_cxxflags">target:add_cxxflags</a>            <ul>
              <li><a href="#add-c-compilation-flags-1" id="markdown-toc-add-c-compilation-flags-1">Add c++ compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_mflags" id="markdown-toc-targetadd_mflags">target:add_mflags</a>            <ul>
              <li><a href="#add-objc-compilation-flags" id="markdown-toc-add-objc-compilation-flags">Add objc compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_mxflags" id="markdown-toc-targetadd_mxflags">target:add_mxflags</a>            <ul>
              <li><a href="#add-objcobjc-compilation-flags" id="markdown-toc-add-objcobjc-compilation-flags">Add objc/objc++ compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_mxxflags" id="markdown-toc-targetadd_mxxflags">target:add_mxxflags</a>            <ul>
              <li><a href="#add-objc-compilation-flags-1" id="markdown-toc-add-objc-compilation-flags-1">Add objc++ compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_scflags" id="markdown-toc-targetadd_scflags">target:add_scflags</a>            <ul>
              <li><a href="#add-swift-compilation-flags" id="markdown-toc-add-swift-compilation-flags">Add swift compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_asflags" id="markdown-toc-targetadd_asflags">target:add_asflags</a>            <ul>
              <li><a href="#add-asm-compilation-flags" id="markdown-toc-add-asm-compilation-flags">Add asm compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_gcflags" id="markdown-toc-targetadd_gcflags">target:add_gcflags</a>            <ul>
              <li><a href="#add-go-compilation-flags" id="markdown-toc-add-go-compilation-flags">Add go compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_dcflags" id="markdown-toc-targetadd_dcflags">target:add_dcflags</a>            <ul>
              <li><a href="#add-dlang-compilation-flags" id="markdown-toc-add-dlang-compilation-flags">Add dlang compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_rcflags" id="markdown-toc-targetadd_rcflags">target:add_rcflags</a>            <ul>
              <li><a href="#add-rust-compilation-flags" id="markdown-toc-add-rust-compilation-flags">Add rust compilation flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_ldflags" id="markdown-toc-targetadd_ldflags">target:add_ldflags</a>            <ul>
              <li><a href="#add-static-library-link-flags" id="markdown-toc-add-static-library-link-flags">Add static library link flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_arflags" id="markdown-toc-targetadd_arflags">target:add_arflags</a>            <ul>
              <li><a href="#add-archive-library-flags" id="markdown-toc-add-archive-library-flags">Add archive library flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_shflags" id="markdown-toc-targetadd_shflags">target:add_shflags</a>            <ul>
              <li><a href="#add-dynamic-library-link-flags" id="markdown-toc-add-dynamic-library-link-flags">Add dynamic library link flags</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cfunc" id="markdown-toc-targetadd_cfunc">target:add_cfunc</a>            <ul>
              <li><a href="#add-single-c-function-for-checking" id="markdown-toc-add-single-c-function-for-checking">Add single c function for checking</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cxxfunc" id="markdown-toc-targetadd_cxxfunc">target:add_cxxfunc</a>            <ul>
              <li><a href="#add-single-c-function-for-checking-1" id="markdown-toc-add-single-c-function-for-checking-1">Add single c++ function for checking</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cfuncs" id="markdown-toc-targetadd_cfuncs">target:add_cfuncs</a>            <ul>
              <li><a href="#add-c-functions-for-checking" id="markdown-toc-add-c-functions-for-checking">Add c functions for checking</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_cxxfuncs" id="markdown-toc-targetadd_cxxfuncs">target:add_cxxfuncs</a>            <ul>
              <li><a href="#add-c-functions-for-checking-1" id="markdown-toc-add-c-functions-for-checking-1">Add c++ functions for checking</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_options" id="markdown-toc-targetadd_options">target:add_options</a>            <ul>
              <li><a href="#add-option-dependencies" id="markdown-toc-add-option-dependencies">Add option dependencies</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_packages" id="markdown-toc-targetadd_packages">target:add_packages</a>            <ul>
              <li><a href="#add-package-dependencies" id="markdown-toc-add-package-dependencies">Add package dependencies</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_languages" id="markdown-toc-targetadd_languages">target:add_languages</a>            <ul>
              <li><a href="#add-language-standards" id="markdown-toc-add-language-standards">Add language standards</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_vectorexts" id="markdown-toc-targetadd_vectorexts">target:add_vectorexts</a>            <ul>
              <li><a href="#add-vector-extensions" id="markdown-toc-add-vector-extensions">Add vector extensions</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_frameworks" id="markdown-toc-targetadd_frameworks">target:add_frameworks</a>            <ul>
              <li><a href="#add-frameworks" id="markdown-toc-add-frameworks">Add frameworks</a></li>
            </ul>
          </li>
          <li><a href="#targetadd_frameworkdirs" id="markdown-toc-targetadd_frameworkdirs">target:add_frameworkdirs</a>            <ul>
              <li><a href="#add-framework-search-directories" id="markdown-toc-add-framework-search-directories">Add framework search directories</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#configuration-option" id="markdown-toc-configuration-option">Configuration Option</a>        <ul>
          <li><a href="#option" id="markdown-toc-option">option</a>            <ul>
              <li><a href="#定义选项" id="markdown-toc-定义选项">定义选项</a></li>
            </ul>
          </li>
          <li><a href="#option_end" id="markdown-toc-option_end">option_end</a>            <ul>
              <li><a href="#结束定义选项" id="markdown-toc-结束定义选项">结束定义选项</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_deps" id="markdown-toc-optionadd_deps">option:add_deps</a>            <ul>
              <li><a href="#添加选项依赖" id="markdown-toc-添加选项依赖">添加选项依赖</a></li>
            </ul>
          </li>
          <li><a href="#optionbefore_check" id="markdown-toc-optionbefore_check">option:before_check</a>            <ul>
              <li><a href="#选项检测之前执行此脚本" id="markdown-toc-选项检测之前执行此脚本">选项检测之前执行此脚本</a></li>
            </ul>
          </li>
          <li><a href="#optionon_check" id="markdown-toc-optionon_check">option:on_check</a>            <ul>
              <li><a href="#自定义选项检测脚本" id="markdown-toc-自定义选项检测脚本">自定义选项检测脚本</a></li>
            </ul>
          </li>
          <li><a href="#optionafter_check" id="markdown-toc-optionafter_check">option:after_check</a>            <ul>
              <li><a href="#选项检测之后执行此脚本" id="markdown-toc-选项检测之后执行此脚本">选项检测之后执行此脚本</a></li>
            </ul>
          </li>
          <li><a href="#optionset_values" id="markdown-toc-optionset_values">option:set_values</a>            <ul>
              <li><a href="#设置选项值列表" id="markdown-toc-设置选项值列表">设置选项值列表</a></li>
            </ul>
          </li>
          <li><a href="#optionset_default" id="markdown-toc-optionset_default">option:set_default</a>            <ul>
              <li><a href="#设置选项默认值" id="markdown-toc-设置选项默认值">设置选项默认值</a></li>
            </ul>
          </li>
          <li><a href="#optionset_showmenu" id="markdown-toc-optionset_showmenu">option:set_showmenu</a>            <ul>
              <li><a href="#设置是否启用菜单显示" id="markdown-toc-设置是否启用菜单显示">设置是否启用菜单显示</a></li>
            </ul>
          </li>
          <li><a href="#optionset_category" id="markdown-toc-optionset_category">option:set_category</a>            <ul>
              <li><a href="#设置选项分类仅用于菜单显示" id="markdown-toc-设置选项分类仅用于菜单显示">设置选项分类，仅用于菜单显示</a></li>
            </ul>
          </li>
          <li><a href="#optionset_description" id="markdown-toc-optionset_description">option:set_description</a>            <ul>
              <li><a href="#设置菜单显示描述" id="markdown-toc-设置菜单显示描述">设置菜单显示描述</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_bindings" id="markdown-toc-optionadd_bindings">option:add_bindings</a>            <ul>
              <li><a href="#添加正向关联选项同步启用和禁用" id="markdown-toc-添加正向关联选项同步启用和禁用">添加正向关联选项，同步启用和禁用</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_rbindings" id="markdown-toc-optionadd_rbindings">option:add_rbindings</a>            <ul>
              <li><a href="#添加逆向关联选项同步启用和禁用" id="markdown-toc-添加逆向关联选项同步启用和禁用">添加逆向关联选项，同步启用和禁用</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_links" id="markdown-toc-optionadd_links">option:add_links</a>            <ul>
              <li><a href="#添加链接库检测" id="markdown-toc-添加链接库检测">添加链接库检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_linkdirs" id="markdown-toc-optionadd_linkdirs">option:add_linkdirs</a>            <ul>
              <li><a href="#添加链接库检测时候需要的搜索目录" id="markdown-toc-添加链接库检测时候需要的搜索目录">添加链接库检测时候需要的搜索目录</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_rpathdirs" id="markdown-toc-optionadd_rpathdirs">option:add_rpathdirs</a>            <ul>
              <li><a href="#添加程序运行时动态库的加载搜索目录" id="markdown-toc-添加程序运行时动态库的加载搜索目录">添加程序运行时动态库的加载搜索目录</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_cincludes" id="markdown-toc-optionadd_cincludes">option:add_cincludes</a>            <ul>
              <li><a href="#添加c头文件检测" id="markdown-toc-添加c头文件检测">添加c头文件检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_cxxincludes" id="markdown-toc-optionadd_cxxincludes">option:add_cxxincludes</a>            <ul>
              <li><a href="#添加c头文件检测-1" id="markdown-toc-添加c头文件检测-1">添加c++头文件检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_ctypes" id="markdown-toc-optionadd_ctypes">option:add_ctypes</a>            <ul>
              <li><a href="#添加c类型检测" id="markdown-toc-添加c类型检测">添加c类型检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_cxxtypes" id="markdown-toc-optionadd_cxxtypes">option:add_cxxtypes</a>            <ul>
              <li><a href="#添加c类型检测-1" id="markdown-toc-添加c类型检测-1">添加c++类型检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_csnippet" id="markdown-toc-optionadd_csnippet">option:add_csnippet</a>            <ul>
              <li><a href="#添加c代码片段检测" id="markdown-toc-添加c代码片段检测">添加c代码片段检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_cxxsnippet" id="markdown-toc-optionadd_cxxsnippet">option:add_cxxsnippet</a>            <ul>
              <li><a href="#添加c代码片段检测-1" id="markdown-toc-添加c代码片段检测-1">添加c++代码片段检测</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_defines_if_ok" id="markdown-toc-optionadd_defines_if_ok">option:add_defines_if_ok</a>            <ul>
              <li><a href="#如果检测选项通过则添加宏定义" id="markdown-toc-如果检测选项通过则添加宏定义">如果检测选项通过，则添加宏定义</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_defines_h_if_ok" id="markdown-toc-optionadd_defines_h_if_ok">option:add_defines_h_if_ok</a>            <ul>
              <li><a href="#如果检测选项通过则添加宏定义到配置头文件" id="markdown-toc-如果检测选项通过则添加宏定义到配置头文件">如果检测选项通过，则添加宏定义到配置头文件</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_undefines_if_ok" id="markdown-toc-optionadd_undefines_if_ok">option:add_undefines_if_ok</a>            <ul>
              <li><a href="#如果检测选项通过则取消宏定义" id="markdown-toc-如果检测选项通过则取消宏定义">如果检测选项通过，则取消宏定义</a></li>
            </ul>
          </li>
          <li><a href="#optionadd_undefines_h_if_ok" id="markdown-toc-optionadd_undefines_h_if_ok">option:add_undefines_h_if_ok</a>            <ul>
              <li><a href="#如果检测选项通过则在配置头文件中取消宏定义" id="markdown-toc-如果检测选项通过则在配置头文件中取消宏定义">如果检测选项通过，则在配置头文件中取消宏定义</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#plugin-and-task" id="markdown-toc-plugin-and-task">Plugin and Task</a>        <ul>
          <li><a href="#task" id="markdown-toc-task">task</a>            <ul>
              <li><a href="#定义插件或者任务" id="markdown-toc-定义插件或者任务">定义插件或者任务</a></li>
            </ul>
          </li>
          <li><a href="#task_end" id="markdown-toc-task_end">task_end</a>            <ul>
              <li><a href="#结束定义插件或任务" id="markdown-toc-结束定义插件或任务">结束定义插件或任务</a></li>
            </ul>
          </li>
          <li><a href="#taskset_menu" id="markdown-toc-taskset_menu">task:set_menu</a>            <ul>
              <li><a href="#设置任务菜单" id="markdown-toc-设置任务菜单">设置任务菜单</a></li>
            </ul>
          </li>
          <li><a href="#taskset_category" id="markdown-toc-taskset_category">task:set_category</a>            <ul>
              <li><a href="#设置任务类别" id="markdown-toc-设置任务类别">设置任务类别</a></li>
            </ul>
          </li>
          <li><a href="#taskon_run" id="markdown-toc-taskon_run">task:on_run</a>            <ul>
              <li><a href="#设置任务运行脚本" id="markdown-toc-设置任务运行脚本">设置任务运行脚本</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#custom-rule" id="markdown-toc-custom-rule">Custom Rule</a>        <ul>
          <li><a href="#rule" id="markdown-toc-rule">rule</a>            <ul>
              <li><a href="#定义规则" id="markdown-toc-定义规则">定义规则</a></li>
            </ul>
          </li>
          <li><a href="#ruleadd_imports" id="markdown-toc-ruleadd_imports">rule:add_imports</a>            <ul>
              <li><a href="#为所有自定义脚本预先导入扩展模块" id="markdown-toc-为所有自定义脚本预先导入扩展模块">为所有自定义脚本预先导入扩展模块</a></li>
            </ul>
          </li>
          <li><a href="#ruleset_extensions" id="markdown-toc-ruleset_extensions">rule:set_extensions</a>            <ul>
              <li><a href="#设置规则支持的文件扩展类型" id="markdown-toc-设置规则支持的文件扩展类型">设置规则支持的文件扩展类型</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_build" id="markdown-toc-ruleon_build">rule:on_build</a>            <ul>
              <li><a href="#自定义编译脚本" id="markdown-toc-自定义编译脚本">自定义编译脚本</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_clean" id="markdown-toc-ruleon_clean">rule:on_clean</a>            <ul>
              <li><a href="#自定义清理脚本" id="markdown-toc-自定义清理脚本">自定义清理脚本</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_package" id="markdown-toc-ruleon_package">rule:on_package</a>            <ul>
              <li><a href="#自定义打包脚本" id="markdown-toc-自定义打包脚本">自定义打包脚本</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_install" id="markdown-toc-ruleon_install">rule:on_install</a>            <ul>
              <li><a href="#自定义安装脚本" id="markdown-toc-自定义安装脚本">自定义安装脚本</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_uninstall" id="markdown-toc-ruleon_uninstall">rule:on_uninstall</a>            <ul>
              <li><a href="#自定义卸载脚本" id="markdown-toc-自定义卸载脚本">自定义卸载脚本</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_build_all" id="markdown-toc-ruleon_build_all">rule:on_build_all</a>            <ul>
              <li><a href="#自定义编译脚本一次处理多个源文件" id="markdown-toc-自定义编译脚本一次处理多个源文件">自定义编译脚本，一次处理多个源文件</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_clean_all" id="markdown-toc-ruleon_clean_all">rule:on_clean_all</a>            <ul>
              <li><a href="#自定义清理脚本一次处理多个源文件" id="markdown-toc-自定义清理脚本一次处理多个源文件">自定义清理脚本，一次处理多个源文件</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_package_all" id="markdown-toc-ruleon_package_all">rule:on_package_all</a>            <ul>
              <li><a href="#自定义打包脚本一次处理多个源文件" id="markdown-toc-自定义打包脚本一次处理多个源文件">自定义打包脚本，一次处理多个源文件</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_install_all" id="markdown-toc-ruleon_install_all">rule:on_install_all</a>            <ul>
              <li><a href="#自定义安装脚本一次处理多个源文件" id="markdown-toc-自定义安装脚本一次处理多个源文件">自定义安装脚本，一次处理多个源文件</a></li>
            </ul>
          </li>
          <li><a href="#ruleon_uninstall_all" id="markdown-toc-ruleon_uninstall_all">rule:on_uninstall_all</a>            <ul>
              <li><a href="#自定义卸载脚本一次处理多个源文件" id="markdown-toc-自定义卸载脚本一次处理多个源文件">自定义卸载脚本，一次处理多个源文件</a></li>
            </ul>
          </li>
          <li><a href="#rule_end" id="markdown-toc-rule_end">rule_end</a>            <ul>
              <li><a href="#结束定义规则" id="markdown-toc-结束定义规则">结束定义规则</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#extension-platforms" id="markdown-toc-extension-platforms">Extension Platforms</a>        <ul>
          <li><a href="#platform" id="markdown-toc-platform">platform</a>            <ul>
              <li><a href="#定义平台" id="markdown-toc-定义平台">定义平台</a></li>
            </ul>
          </li>
          <li><a href="#platform_end" id="markdown-toc-platform_end">platform_end</a>            <ul>
              <li><a href="#结束定义平台" id="markdown-toc-结束定义平台">结束定义平台</a></li>
            </ul>
          </li>
          <li><a href="#set_os" id="markdown-toc-set_os">set_os</a>            <ul>
              <li><a href="#设置平台系统" id="markdown-toc-设置平台系统">设置平台系统</a></li>
            </ul>
          </li>
          <li><a href="#set_menu" id="markdown-toc-set_menu">set_menu</a>            <ul>
              <li><a href="#设置平台菜单" id="markdown-toc-设置平台菜单">设置平台菜单</a></li>
            </ul>
          </li>
          <li><a href="#set_hosts" id="markdown-toc-set_hosts">set_hosts</a>            <ul>
              <li><a href="#设置平台支持的主机环境" id="markdown-toc-设置平台支持的主机环境">设置平台支持的主机环境</a></li>
            </ul>
          </li>
          <li><a href="#set_archs" id="markdown-toc-set_archs">set_archs</a>            <ul>
              <li><a href="#设置平台支持的架构环境" id="markdown-toc-设置平台支持的架构环境">设置平台支持的架构环境</a></li>
            </ul>
          </li>
          <li><a href="#set_tooldirs" id="markdown-toc-set_tooldirs">set_tooldirs</a>            <ul>
              <li><a href="#设置平台工具的搜索目录" id="markdown-toc-设置平台工具的搜索目录">设置平台工具的搜索目录</a></li>
            </ul>
          </li>
          <li><a href="#on_load" id="markdown-toc-on_load">on_load</a>            <ul>
              <li><a href="#设置加载平台环境配置脚本" id="markdown-toc-设置加载平台环境配置脚本">设置加载平台环境配置脚本</a></li>
            </ul>
          </li>
          <li><a href="#on_check" id="markdown-toc-on_check">on_check</a>            <ul>
              <li><a href="#设置平台工具的检测脚本" id="markdown-toc-设置平台工具的检测脚本">设置平台工具的检测脚本</a></li>
            </ul>
          </li>
          <li><a href="#on_install" id="markdown-toc-on_install">on_install</a>            <ul>
              <li><a href="#设置目标工程在指定平台的安装脚本" id="markdown-toc-设置目标工程在指定平台的安装脚本">设置目标工程在指定平台的安装脚本</a></li>
            </ul>
          </li>
          <li><a href="#on_uninstall" id="markdown-toc-on_uninstall">on_uninstall</a>            <ul>
              <li><a href="#设置目标工程在指定平台的卸载脚本" id="markdown-toc-设置目标工程在指定平台的卸载脚本">设置目标工程在指定平台的卸载脚本</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#extension-languages" id="markdown-toc-extension-languages">Extension Languages</a></li>
      <li><a href="#project-templates" id="markdown-toc-project-templates">Project Templates</a>        <ul>
          <li><a href="#template" id="markdown-toc-template">template</a></li>
          <li><a href="#set_description" id="markdown-toc-set_description">set_description</a></li>
          <li><a href="#set_projectdir" id="markdown-toc-set_projectdir">set_projectdir</a></li>
          <li><a href="#add_macros" id="markdown-toc-add_macros">add_macros</a></li>
          <li><a href="#add_macrofiles" id="markdown-toc-add_macrofiles">add_macrofiles</a></li>
        </ul>
      </li>
      <li><a href="#builtin-variables" id="markdown-toc-builtin-variables">Builtin Variables</a>        <ul>
          <li><a href="#varos" id="markdown-toc-varos">var.$(os)</a>            <ul>
              <li><a href="#获取当前编译平台的操作系统" id="markdown-toc-获取当前编译平台的操作系统">获取当前编译平台的操作系统</a></li>
            </ul>
          </li>
          <li><a href="#varhost" id="markdown-toc-varhost">var.$(host)</a>            <ul>
              <li><a href="#获取本机操作系统" id="markdown-toc-获取本机操作系统">获取本机操作系统</a></li>
            </ul>
          </li>
          <li><a href="#vartmpdir" id="markdown-toc-vartmpdir">var.$(tmpdir)</a>            <ul>
              <li><a href="#获取临时目录" id="markdown-toc-获取临时目录">获取临时目录</a></li>
            </ul>
          </li>
          <li><a href="#varcurdir" id="markdown-toc-varcurdir">var.$(curdir)</a>            <ul>
              <li><a href="#获取当前目录" id="markdown-toc-获取当前目录">获取当前目录</a></li>
            </ul>
          </li>
          <li><a href="#varbuildir" id="markdown-toc-varbuildir">var.$(buildir)</a>            <ul>
              <li><a href="#获取当前的构建输出目录" id="markdown-toc-获取当前的构建输出目录">获取当前的构建输出目录</a></li>
            </ul>
          </li>
          <li><a href="#varscriptdir" id="markdown-toc-varscriptdir">var.$(scriptdir)</a>            <ul>
              <li><a href="#获取当前工程描述脚本的目录" id="markdown-toc-获取当前工程描述脚本的目录">获取当前工程描述脚本的目录</a></li>
            </ul>
          </li>
          <li><a href="#varglobaldir" id="markdown-toc-varglobaldir">var.$(globaldir)</a>            <ul>
              <li><a href="#全局配置目录" id="markdown-toc-全局配置目录">全局配置目录</a></li>
            </ul>
          </li>
          <li><a href="#varconfigdir" id="markdown-toc-varconfigdir">var.$(configdir)</a>            <ul>
              <li><a href="#当前工程配置目录" id="markdown-toc-当前工程配置目录">当前工程配置目录</a></li>
            </ul>
          </li>
          <li><a href="#varprogramdir" id="markdown-toc-varprogramdir">var.$(programdir)</a>            <ul>
              <li><a href="#xmake安装脚本目录" id="markdown-toc-xmake安装脚本目录">xmake安装脚本目录</a></li>
            </ul>
          </li>
          <li><a href="#varprojectdir" id="markdown-toc-varprojectdir">var.$(projectdir)</a>            <ul>
              <li><a href="#工程根目录" id="markdown-toc-工程根目录">工程根目录</a></li>
            </ul>
          </li>
          <li><a href="#varshell" id="markdown-toc-varshell">var.$(shell)</a>            <ul>
              <li><a href="#执行外部shell命令" id="markdown-toc-执行外部shell命令">执行外部shell命令</a></li>
            </ul>
          </li>
          <li><a href="#varenv" id="markdown-toc-varenv">var.$(env)</a>            <ul>
              <li><a href="#获取外部环境变量" id="markdown-toc-获取外部环境变量">获取外部环境变量</a></li>
            </ul>
          </li>
          <li><a href="#varreg" id="markdown-toc-varreg">var.$(reg)</a>            <ul>
              <li><a href="#获取windows注册表配置项的值" id="markdown-toc-获取windows注册表配置项的值">获取windows注册表配置项的值</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#builtin-modules" id="markdown-toc-builtin-modules">Builtin Modules</a>        <ul>
          <li><a href="#val" id="markdown-toc-val">val</a>            <ul>
              <li><a href="#获取内置变量的值" id="markdown-toc-获取内置变量的值">获取内置变量的值</a></li>
            </ul>
          </li>
          <li><a href="#import" id="markdown-toc-import">import</a>            <ul>
              <li><a href="#导入扩展摸块" id="markdown-toc-导入扩展摸块">导入扩展摸块</a></li>
            </ul>
          </li>
          <li><a href="#inherit" id="markdown-toc-inherit">inherit</a>            <ul>
              <li><a href="#导入并继承基类模块" id="markdown-toc-导入并继承基类模块">导入并继承基类模块</a></li>
            </ul>
          </li>
          <li><a href="#ifelse" id="markdown-toc-ifelse">ifelse</a>            <ul>
              <li><a href="#类似三元条件判断" id="markdown-toc-类似三元条件判断">类似三元条件判断</a></li>
            </ul>
          </li>
          <li><a href="#try-catch-finally" id="markdown-toc-try-catch-finally">try-catch-finally</a>            <ul>
              <li><a href="#异常捕获" id="markdown-toc-异常捕获">异常捕获</a></li>
            </ul>
          </li>
          <li><a href="#pairs" id="markdown-toc-pairs">pairs</a>            <ul>
              <li><a href="#用于遍历字典" id="markdown-toc-用于遍历字典">用于遍历字典</a></li>
            </ul>
          </li>
          <li><a href="#ipairs" id="markdown-toc-ipairs">ipairs</a>            <ul>
              <li><a href="#用于遍历数组" id="markdown-toc-用于遍历数组">用于遍历数组</a></li>
            </ul>
          </li>
          <li><a href="#print" id="markdown-toc-print">print</a>            <ul>
              <li><a href="#换行打印终端日志" id="markdown-toc-换行打印终端日志">换行打印终端日志</a></li>
            </ul>
          </li>
          <li><a href="#printf" id="markdown-toc-printf">printf</a>            <ul>
              <li><a href="#无换行打印终端日志" id="markdown-toc-无换行打印终端日志">无换行打印终端日志</a></li>
            </ul>
          </li>
          <li><a href="#cprint" id="markdown-toc-cprint">cprint</a>            <ul>
              <li><a href="#换行彩色打印终端日志" id="markdown-toc-换行彩色打印终端日志">换行彩色打印终端日志</a></li>
            </ul>
          </li>
          <li><a href="#cprintf" id="markdown-toc-cprintf">cprintf</a>            <ul>
              <li><a href="#无换行彩色打印终端日志" id="markdown-toc-无换行彩色打印终端日志">无换行彩色打印终端日志</a></li>
            </ul>
          </li>
          <li><a href="#format" id="markdown-toc-format">format</a>            <ul>
              <li><a href="#格式化字符串" id="markdown-toc-格式化字符串">格式化字符串</a></li>
            </ul>
          </li>
          <li><a href="#vformat" id="markdown-toc-vformat">vformat</a>            <ul>
              <li><a href="#格式化字符串支持内置变量转义" id="markdown-toc-格式化字符串支持内置变量转义">格式化字符串，支持内置变量转义</a></li>
            </ul>
          </li>
          <li><a href="#raise" id="markdown-toc-raise">raise</a>            <ul>
              <li><a href="#抛出异常中断程序" id="markdown-toc-抛出异常中断程序">抛出异常中断程序</a></li>
            </ul>
          </li>
          <li><a href="#os" id="markdown-toc-os">os</a>            <ul>
              <li><a href="#oscp" id="markdown-toc-oscp">os.cp</a></li>
              <li><a href="#osmv" id="markdown-toc-osmv">os.mv</a></li>
              <li><a href="#osrm" id="markdown-toc-osrm">os.rm</a></li>
              <li><a href="#ostrycp" id="markdown-toc-ostrycp">os.trycp</a></li>
              <li><a href="#ostrymv" id="markdown-toc-ostrymv">os.trymv</a></li>
              <li><a href="#ostryrm" id="markdown-toc-ostryrm">os.tryrm</a></li>
              <li><a href="#oscd" id="markdown-toc-oscd">os.cd</a></li>
              <li><a href="#osrmdir" id="markdown-toc-osrmdir">os.rmdir</a></li>
              <li><a href="#osmkdir" id="markdown-toc-osmkdir">os.mkdir</a></li>
              <li><a href="#osisdir" id="markdown-toc-osisdir">os.isdir</a></li>
              <li><a href="#osisfile" id="markdown-toc-osisfile">os.isfile</a></li>
              <li><a href="#osexists" id="markdown-toc-osexists">os.exists</a></li>
              <li><a href="#osdirs" id="markdown-toc-osdirs">os.dirs</a></li>
              <li><a href="#osfiles" id="markdown-toc-osfiles">os.files</a></li>
              <li><a href="#osfiledirs" id="markdown-toc-osfiledirs">os.filedirs</a></li>
              <li><a href="#osrun" id="markdown-toc-osrun">os.run</a></li>
              <li><a href="#osrunv" id="markdown-toc-osrunv">os.runv</a></li>
              <li><a href="#osexec" id="markdown-toc-osexec">os.exec</a></li>
              <li><a href="#osexecv" id="markdown-toc-osexecv">os.execv</a></li>
              <li><a href="#osiorun" id="markdown-toc-osiorun">os.iorun</a></li>
              <li><a href="#osiorunv" id="markdown-toc-osiorunv">os.iorunv</a></li>
              <li><a href="#osgetenv" id="markdown-toc-osgetenv">os.getenv</a></li>
              <li><a href="#ossetenv" id="markdown-toc-ossetenv">os.setenv</a></li>
              <li><a href="#ostmpdir" id="markdown-toc-ostmpdir">os.tmpdir</a></li>
              <li><a href="#ostmpfile" id="markdown-toc-ostmpfile">os.tmpfile</a></li>
              <li><a href="#oscurdir" id="markdown-toc-oscurdir">os.curdir</a></li>
              <li><a href="#osfilesize" id="markdown-toc-osfilesize">os.filesize</a></li>
              <li><a href="#osscriptdir" id="markdown-toc-osscriptdir">os.scriptdir</a></li>
              <li><a href="#osprogramdir" id="markdown-toc-osprogramdir">os.programdir</a></li>
              <li><a href="#osprojectdir" id="markdown-toc-osprojectdir">os.projectdir</a></li>
              <li><a href="#osarch" id="markdown-toc-osarch">os.arch</a></li>
              <li><a href="#oshost" id="markdown-toc-oshost">os.host</a></li>
            </ul>
          </li>
          <li><a href="#io" id="markdown-toc-io">io</a>            <ul>
              <li><a href="#ioopen" id="markdown-toc-ioopen">io.open</a></li>
              <li><a href="#ioload" id="markdown-toc-ioload">io.load</a></li>
              <li><a href="#iosave" id="markdown-toc-iosave">io.save</a></li>
              <li><a href="#ioreadfile" id="markdown-toc-ioreadfile">io.readfile</a></li>
              <li><a href="#iowritefile" id="markdown-toc-iowritefile">io.writefile</a></li>
              <li><a href="#iogsub" id="markdown-toc-iogsub">io.gsub</a></li>
              <li><a href="#iotail" id="markdown-toc-iotail">io.tail</a></li>
              <li><a href="#iocat" id="markdown-toc-iocat">io.cat</a></li>
              <li><a href="#ioprint" id="markdown-toc-ioprint">io.print</a></li>
              <li><a href="#ioprintf" id="markdown-toc-ioprintf">io.printf</a></li>
            </ul>
          </li>
          <li><a href="#path" id="markdown-toc-path">path</a>            <ul>
              <li><a href="#pathjoin" id="markdown-toc-pathjoin">path.join</a></li>
              <li><a href="#pathtranslate" id="markdown-toc-pathtranslate">path.translate</a></li>
              <li><a href="#pathbasename" id="markdown-toc-pathbasename">path.basename</a></li>
              <li><a href="#pathfilename" id="markdown-toc-pathfilename">path.filename</a></li>
              <li><a href="#pathextension" id="markdown-toc-pathextension">path.extension</a></li>
              <li><a href="#pathdirectory" id="markdown-toc-pathdirectory">path.directory</a></li>
              <li><a href="#pathrelative" id="markdown-toc-pathrelative">path.relative</a></li>
              <li><a href="#pathabsolute" id="markdown-toc-pathabsolute">path.absolute</a></li>
              <li><a href="#pathis_absolute" id="markdown-toc-pathis_absolute">path.is_absolute</a></li>
            </ul>
          </li>
          <li><a href="#table" id="markdown-toc-table">table</a>            <ul>
              <li><a href="#tablejoin" id="markdown-toc-tablejoin">table.join</a></li>
              <li><a href="#tablejoin2" id="markdown-toc-tablejoin2">table.join2</a></li>
              <li><a href="#tabledump" id="markdown-toc-tabledump">table.dump</a></li>
              <li><a href="#tableunique" id="markdown-toc-tableunique">table.unique</a></li>
              <li><a href="#tableslice" id="markdown-toc-tableslice">table.slice</a></li>
            </ul>
          </li>
          <li><a href="#string" id="markdown-toc-string">string</a>            <ul>
              <li><a href="#stringstartswith" id="markdown-toc-stringstartswith">string.startswith</a></li>
              <li><a href="#stringendswith" id="markdown-toc-stringendswith">string.endswith</a></li>
              <li><a href="#stringsplit" id="markdown-toc-stringsplit">string.split</a></li>
              <li><a href="#stringtrim" id="markdown-toc-stringtrim">string.trim</a></li>
              <li><a href="#stringltrim" id="markdown-toc-stringltrim">string.ltrim</a></li>
              <li><a href="#stringrtrim" id="markdown-toc-stringrtrim">string.rtrim</a></li>
            </ul>
          </li>
          <li><a href="#process" id="markdown-toc-process">process</a>            <ul>
              <li><a href="#processopen" id="markdown-toc-processopen">process.open</a></li>
              <li><a href="#processwait" id="markdown-toc-processwait">process.wait</a></li>
              <li><a href="#processclose" id="markdown-toc-processclose">process.close</a></li>
              <li><a href="#processwaitlist" id="markdown-toc-processwaitlist">process.waitlist</a></li>
            </ul>
          </li>
          <li><a href="#coroutine" id="markdown-toc-coroutine">coroutine</a></li>
        </ul>
      </li>
      <li><a href="#extension-modules" id="markdown-toc-extension-modules">Extension Modules</a>        <ul>
          <li><a href="#corebaseoption" id="markdown-toc-corebaseoption">core.base.option</a>            <ul>
              <li><a href="#optionget" id="markdown-toc-optionget">option.get</a></li>
            </ul>
          </li>
          <li><a href="#corebaseglobal" id="markdown-toc-corebaseglobal">core.base.global</a>            <ul>
              <li><a href="#globalget" id="markdown-toc-globalget">global.get</a></li>
              <li><a href="#globalload" id="markdown-toc-globalload">global.load</a></li>
              <li><a href="#globaldirectory" id="markdown-toc-globaldirectory">global.directory</a></li>
              <li><a href="#globaldump" id="markdown-toc-globaldump">global.dump</a></li>
            </ul>
          </li>
          <li><a href="#corebasetask" id="markdown-toc-corebasetask">core.base.task</a>            <ul>
              <li><a href="#taskrun" id="markdown-toc-taskrun">task.run</a></li>
            </ul>
          </li>
          <li><a href="#coretoollinker" id="markdown-toc-coretoollinker">core.tool.linker</a>            <ul>
              <li><a href="#linkerlink" id="markdown-toc-linkerlink">linker.link</a></li>
              <li><a href="#linkerlinkcmd" id="markdown-toc-linkerlinkcmd">linker.linkcmd</a></li>
              <li><a href="#linkerlinkargv" id="markdown-toc-linkerlinkargv">linker.linkargv</a></li>
              <li><a href="#linkerlinkflags" id="markdown-toc-linkerlinkflags">linker.linkflags</a></li>
              <li><a href="#linkerhas_flags" id="markdown-toc-linkerhas_flags">linker.has_flags</a></li>
            </ul>
          </li>
          <li><a href="#coretoolcompiler" id="markdown-toc-coretoolcompiler">core.tool.compiler</a>            <ul>
              <li><a href="#compilercompile" id="markdown-toc-compilercompile">compiler.compile</a></li>
              <li><a href="#compilercompcmd" id="markdown-toc-compilercompcmd">compiler.compcmd</a></li>
              <li><a href="#compilercompargv" id="markdown-toc-compilercompargv">compiler.compargv</a></li>
              <li><a href="#compilercompflags" id="markdown-toc-compilercompflags">compiler.compflags</a></li>
              <li><a href="#compilerhas_flags" id="markdown-toc-compilerhas_flags">compiler.has_flags</a></li>
              <li><a href="#compilerfeatures" id="markdown-toc-compilerfeatures">compiler.features</a></li>
              <li><a href="#compilerhas_features" id="markdown-toc-compilerhas_features">compiler.has_features</a></li>
            </ul>
          </li>
          <li><a href="#coreprojectconfig" id="markdown-toc-coreprojectconfig">core.project.config</a>            <ul>
              <li><a href="#configget" id="markdown-toc-configget">config.get</a></li>
              <li><a href="#configload" id="markdown-toc-configload">config.load</a></li>
              <li><a href="#configarch" id="markdown-toc-configarch">config.arch</a></li>
              <li><a href="#configplat" id="markdown-toc-configplat">config.plat</a></li>
              <li><a href="#configmode" id="markdown-toc-configmode">config.mode</a></li>
              <li><a href="#configbuildir" id="markdown-toc-configbuildir">config.buildir</a></li>
              <li><a href="#configdirectory" id="markdown-toc-configdirectory">config.directory</a></li>
              <li><a href="#configdump" id="markdown-toc-configdump">config.dump</a></li>
            </ul>
          </li>
          <li><a href="#coreprojectglobal" id="markdown-toc-coreprojectglobal">core.project.global</a></li>
          <li><a href="#coreprojecttask" id="markdown-toc-coreprojecttask">core.project.task</a></li>
          <li><a href="#coreprojectproject" id="markdown-toc-coreprojectproject">core.project.project</a>            <ul>
              <li><a href="#projectload" id="markdown-toc-projectload">project.load</a></li>
              <li><a href="#projectdirectory" id="markdown-toc-projectdirectory">project.directory</a></li>
              <li><a href="#projecttarget" id="markdown-toc-projecttarget">project.target</a></li>
              <li><a href="#projecttargets" id="markdown-toc-projecttargets">project.targets</a></li>
              <li><a href="#projectoption" id="markdown-toc-projectoption">project.option</a></li>
              <li><a href="#projectoptions" id="markdown-toc-projectoptions">project.options</a></li>
              <li><a href="#projectname" id="markdown-toc-projectname">project.name</a></li>
              <li><a href="#projectversion" id="markdown-toc-projectversion">project.version</a></li>
            </ul>
          </li>
          <li><a href="#corelanguagelanguage" id="markdown-toc-corelanguagelanguage">core.language.language</a>            <ul>
              <li><a href="#languageextensions" id="markdown-toc-languageextensions">language.extensions</a></li>
              <li><a href="#languagetargetkinds" id="markdown-toc-languagetargetkinds">language.targetkinds</a></li>
              <li><a href="#languagesourcekinds" id="markdown-toc-languagesourcekinds">language.sourcekinds</a></li>
              <li><a href="#languagesourceflags" id="markdown-toc-languagesourceflags">language.sourceflags</a></li>
              <li><a href="#languageload" id="markdown-toc-languageload">language.load</a></li>
              <li><a href="#languageload_sk" id="markdown-toc-languageload_sk">language.load_sk</a></li>
              <li><a href="#languageload_ex" id="markdown-toc-languageload_ex">language.load_ex</a></li>
              <li><a href="#languagesourcekind_of" id="markdown-toc-languagesourcekind_of">language.sourcekind_of</a></li>
            </ul>
          </li>
          <li><a href="#coreplatformplatform" id="markdown-toc-coreplatformplatform">core.platform.platform</a>            <ul>
              <li><a href="#platformget" id="markdown-toc-platformget">platform.get</a></li>
            </ul>
          </li>
          <li><a href="#coreplatformenvironment" id="markdown-toc-coreplatformenvironment">core.platform.environment</a>            <ul>
              <li><a href="#environmententer" id="markdown-toc-environmententer">environment.enter</a></li>
              <li><a href="#environmentleave" id="markdown-toc-environmentleave">environment.leave</a></li>
            </ul>
          </li>
          <li><a href="#libdetect" id="markdown-toc-libdetect">lib.detect</a>            <ul>
              <li><a href="#detectfind_file" id="markdown-toc-detectfind_file">detect.find_file</a></li>
              <li><a href="#detectfind_path" id="markdown-toc-detectfind_path">detect.find_path</a></li>
              <li><a href="#detectfind_library" id="markdown-toc-detectfind_library">detect.find_library</a></li>
              <li><a href="#detectfind_program" id="markdown-toc-detectfind_program">detect.find_program</a></li>
              <li><a href="#detectfind_programver" id="markdown-toc-detectfind_programver">detect.find_programver</a></li>
              <li><a href="#detectfind_package" id="markdown-toc-detectfind_package">detect.find_package</a></li>
              <li><a href="#detectfind_tool" id="markdown-toc-detectfind_tool">detect.find_tool</a></li>
              <li><a href="#detectfind_toolname" id="markdown-toc-detectfind_toolname">detect.find_toolname</a></li>
              <li><a href="#detectfeatures" id="markdown-toc-detectfeatures">detect.features</a></li>
              <li><a href="#detecthas_features" id="markdown-toc-detecthas_features">detect.has_features</a></li>
              <li><a href="#detecthas_flags" id="markdown-toc-detecthas_flags">detect.has_flags</a></li>
              <li><a href="#detecthas_cfuncs" id="markdown-toc-detecthas_cfuncs">detect.has_cfuncs</a></li>
              <li><a href="#detecthas_cxxfuncs" id="markdown-toc-detecthas_cxxfuncs">detect.has_cxxfuncs</a></li>
              <li><a href="#detecthas_cincludes" id="markdown-toc-detecthas_cincludes">detect.has_cincludes</a></li>
              <li><a href="#detecthas_cxxincludes" id="markdown-toc-detecthas_cxxincludes">detect.has_cxxincludes</a></li>
              <li><a href="#detecthas_ctypes" id="markdown-toc-detecthas_ctypes">detect.has_ctypes</a></li>
              <li><a href="#detecthas_cxxtypes" id="markdown-toc-detecthas_cxxtypes">detect.has_cxxtypes</a></li>
              <li><a href="#detectcheck_cxsnippets" id="markdown-toc-detectcheck_cxsnippets">detect.check_cxsnippets</a></li>
            </ul>
          </li>
          <li><a href="#nethttp" id="markdown-toc-nethttp">net.http</a>            <ul>
              <li><a href="#httpdownload" id="markdown-toc-httpdownload">http.download</a></li>
            </ul>
          </li>
          <li><a href="#privilegesudo" id="markdown-toc-privilegesudo">privilege.sudo</a>            <ul>
              <li><a href="#sudohas" id="markdown-toc-sudohas">sudo.has</a></li>
              <li><a href="#sudorun" id="markdown-toc-sudorun">sudo.run</a></li>
              <li><a href="#sudorunv" id="markdown-toc-sudorunv">sudo.runv</a></li>
              <li><a href="#sudoexec" id="markdown-toc-sudoexec">sudo.exec</a></li>
              <li><a href="#sudoexecv" id="markdown-toc-sudoexecv">sudo.execv</a></li>
              <li><a href="#sudoiorun" id="markdown-toc-sudoiorun">sudo.iorun</a></li>
              <li><a href="#sudoiorunv" id="markdown-toc-sudoiorunv">sudo.iorunv</a></li>
            </ul>
          </li>
          <li><a href="#develgit" id="markdown-toc-develgit">devel.git</a>            <ul>
              <li><a href="#gitclone" id="markdown-toc-gitclone">git.clone</a></li>
              <li><a href="#gitpull" id="markdown-toc-gitpull">git.pull</a></li>
              <li><a href="#gitclean" id="markdown-toc-gitclean">git.clean</a></li>
              <li><a href="#gitcheckout" id="markdown-toc-gitcheckout">git.checkout</a></li>
              <li><a href="#gitrefs" id="markdown-toc-gitrefs">git.refs</a></li>
              <li><a href="#gittags" id="markdown-toc-gittags">git.tags</a></li>
              <li><a href="#gitbranches" id="markdown-toc-gitbranches">git.branches</a></li>
            </ul>
          </li>
          <li><a href="#utilsarchive" id="markdown-toc-utilsarchive">utils.archive</a>            <ul>
              <li><a href="#archiveextract" id="markdown-toc-archiveextract">archive.extract</a></li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<p>Note: This documents is only a mirror, if you want to see newest documents please goto: <a href="http://xmake.io/#/manual">http://xmake.io/#/manual</a></p>

<h2 id="specification">Specification</h2>

<h4 id="naming-conventions">Naming conventions</h4>

<p>The interface is named according to some of the predefined specifications, which is more convenient to understand and easy to use.</p>

<p>It’s according to the following rules:</p>

<table>
  <thead>
    <tr>
      <th>Interfaces</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="highlighter-rouge">is_</code> + xxx</td>
      <td>Condition interfaces</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">set_</code> + xxx</td>
      <td>Set and override the previous settings</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">add_</code> + xxx</td>
      <td>Set and append settings</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">s</code> + xxx</td>
      <td>Support multi-parameters, .e.g：<code class="highlighter-rouge">add_files("*.c", "test.cpp")</code></td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">on_</code> + xxx</td>
      <td>Set and override builtin script</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">before_</code> + xxx</td>
      <td>Set and run this script before running builtin-script</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">after_</code> + xxx</td>
      <td>Set and run this script after running builtin-script</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">scope("name")</code></td>
      <td>Define a description scope, .e.g <code class="highlighter-rouge">target("xxx")</code>, <code class="highlighter-rouge">option("xxx")</code></td>
    </tr>
    <tr>
      <td>scope/settings</td>
      <td>Indentation with spaces</td>
    </tr>
  </tbody>
</table>

<h2 id="documentation">Documentation</h2>

<h4 id="conditions">Conditions</h4>

<p>Conditions are generally used to handle some special compilation platforms.</p>

<table>
  <thead>
    <tr>
      <th>Interfaces</th>
      <th>Description</th>
      <th>Support version</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#is_os">is_os</a></td>
      <td>Is the current compilation target system?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#is_arch">is_arch</a></td>
      <td>Is the current compilation architecture?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#is_plat">is_plat</a></td>
      <td>Is the current compilation platform?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#is_host">is_host</a></td>
      <td>Is the current compilation host system?</td>
      <td>&gt;= 2.1.4</td>
    </tr>
    <tr>
      <td><a href="#is_mode">is_mode</a></td>
      <td>Is the current compilation mode?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#is_kind">is_kind</a></td>
      <td>Is the current target kind?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#is_option">is_option</a></td>
      <td>Is the given options enabled?</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h5 id="is_os">is_os</h5>

<h6 id="is-the-current-compilation-target-system">Is the current compilation target system</h6>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">is_os</span><span class="p">(</span><span class="s2">"ios"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/xxx/*.m"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>Support operation systems:</p>

<ul>
  <li>windows</li>
  <li>linux</li>
  <li>android</li>
  <li>macosx</li>
  <li>ios</li>
</ul>

<h5 id="is_arch">is_arch</h5>

<h6 id="is-the-current-compilation-architecture">Is the current compilation architecture</h6>

<p>You can this api to check the configuration command: <code class="highlighter-rouge">xmake f -a armv7</code></p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- if the current architecture is x86_64 or i386</span>
<span class="k">if</span> <span class="n">is_arch</span><span class="p">(</span><span class="s2">"x86_64"</span><span class="p">,</span> <span class="s2">"i386"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/xxx/*.c"</span><span class="p">)</span>
<span class="k">end</span>

<span class="c1">-- if the current architecture is armv7 or arm64 or armv7s or armv7-a</span>
<span class="k">if</span> <span class="n">is_arch</span><span class="p">(</span><span class="s2">"armv7"</span><span class="p">,</span> <span class="s2">"arm64"</span><span class="p">,</span> <span class="s2">"armv7s"</span><span class="p">,</span> <span class="s2">"armv7-a"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<p>And you can also use the wildchard: <code class="highlighter-rouge">*</code> to check all matched architectures.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- if the current architecture is arm which contains armv7, arm64, armv7s and armv7-a ...</span>
<span class="k">if</span> <span class="n">is_arch</span><span class="p">(</span><span class="s2">"arm*"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="is_plat">is_plat</h5>

<h6 id="is-the-current-compilation-platform">Is the current compilation platform</h6>

<p>You can this api to check the configuration command: <code class="highlighter-rouge">xmake f -p iphoneos</code></p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- if the current platform is android</span>
<span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"android"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/xxx/*.c"</span><span class="p">)</span>
<span class="k">end</span>

<span class="c1">-- if the current platform is macosx or iphoneos</span>
<span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"macosx"</span><span class="p">,</span> <span class="s2">"iphoneos"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_mxflags</span><span class="p">(</span><span class="s2">"-framework Foundation"</span><span class="p">)</span>
    <span class="n">add_ldflags</span><span class="p">(</span><span class="s2">"-framework Foundation"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>Support platforms:</p>

<ul>
  <li>windows</li>
  <li>linux</li>
  <li>macosx</li>
  <li>android</li>
  <li>iphoneos</li>
  <li>watchos</li>
</ul>

<h5 id="is_host">is_host</h5>

<h6 id="is-the-current-compilation-host-system">Is the current compilation host system</h6>

<p>Some compilation platforms can be built on multiple different operating systems, for example: android ndk (on linux, macOS and windows).</p>

<p>So, we can use this api to determine the current host operating system.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">is_host</span><span class="p">(</span><span class="s2">"windows"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_includes</span><span class="p">(</span><span class="s2">"C:\\includes"</span><span class="p">)</span>
<span class="k">else</span>
    <span class="n">add_includes</span><span class="p">(</span><span class="s2">"/usr/includess"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>Support hosts:</p>

<ul>
  <li>windows</li>
  <li>linux</li>
  <li>macosx</li>
</ul>

<p>We can also get it from <a href="#var-host">$(host)</a> or <a href="#os-host">os.host</a>.</p>

<h5 id="is_mode">is_mode</h5>

<h6 id="is-the-current-compilation-mode">Is the current compilation mode</h6>

<p>You can this api to check the configuration command: <code class="highlighter-rouge">xmake f -m debug</code></p>

<p>The compilation mode is not builtin mode for xmake, so you can set the mode value by yourself.</p>

<p>We often use these configuration values: <code class="highlighter-rouge">debug</code>, <code class="highlighter-rouge">release</code>, <code class="highlighter-rouge">profile</code>, etc.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- if the current compilation mode is debug?</span>
<span class="k">if</span> <span class="n">is_mode</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">)</span> <span class="k">then</span>

    <span class="c1">-- add macro: DEBUG</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>

    <span class="c1">-- enable debug symbols</span>
    <span class="n">set_symbols</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">)</span>

    <span class="c1">-- 禁用优化</span>
    <span class="n">set_optimize</span><span class="p">(</span><span class="s2">"none"</span><span class="p">)</span>

<span class="k">end</span>

<span class="c1">-- if the current compilation mode is release or profile?</span>
<span class="k">if</span> <span class="n">is_mode</span><span class="p">(</span><span class="s2">"release"</span><span class="p">,</span> <span class="s2">"profile"</span><span class="p">)</span> <span class="k">then</span>

    <span class="k">if</span> <span class="n">is_mode</span><span class="p">(</span><span class="s2">"release"</span><span class="p">)</span> <span class="k">then</span>

        <span class="c1">-- mark symbols visibility as hidden</span>
        <span class="n">set_symbols</span><span class="p">(</span><span class="s2">"hidden"</span><span class="p">)</span>

        <span class="c1">-- strip all symbols</span>
        <span class="n">set_strip</span><span class="p">(</span><span class="s2">"all"</span><span class="p">)</span>

        <span class="c1">-- fomit frame pointer</span>
        <span class="n">add_cxflags</span><span class="p">(</span><span class="s2">"-fomit-frame-pointer"</span><span class="p">)</span>
        <span class="n">add_mxflags</span><span class="p">(</span><span class="s2">"-fomit-frame-pointer"</span><span class="p">)</span>

    <span class="k">else</span>

        <span class="c1">-- enable debug symbols</span>
        <span class="n">set_symbols</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">)</span>

    <span class="k">end</span>

    <span class="c1">-- add vectorexts</span>
    <span class="n">add_vectorexts</span><span class="p">(</span><span class="s2">"sse2"</span><span class="p">,</span> <span class="s2">"sse3"</span><span class="p">,</span> <span class="s2">"ssse3"</span><span class="p">,</span> <span class="s2">"mmx"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="is_kind">is_kind</h5>

<h6 id="is-the-current-target-kind">Is the current target kind</h6>

<p>You can this api to check the configuration command: <code class="highlighter-rouge">xmake f -k [static|shared]</code></p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- set target kind from the configuration command</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"$(kind)"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*c"</span><span class="p">)</span>

    <span class="c1">-- compile target for static?</span>
    <span class="k">if</span> <span class="n">is_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span> <span class="k">then</span>
        <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/xxx.c"</span><span class="p">)</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>You can switch the target kind by configuration command.</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="c"># compile the static library</span>
<span class="gp">$ </span>xmake f -k static
<span class="gp">$ </span>xmake
</code></pre>
</div>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="c"># compile the shared library</span>
<span class="gp">$ </span>xmake f -k shared
<span class="gp">$ </span>xmake
</code></pre>
</div>

<h5 id="is_option">is_option</h5>

<h6 id="is-the-given-options-enabled">Is the given options enabled</h6>

<p>You can this api to check the custom option configuration command：<code class="highlighter-rouge">xmake f --xxxx=y</code></p>

<p>For example, We want to enable the custom option: <code class="highlighter-rouge">xmake f --demo=y</code> and check it from <code class="highlighter-rouge">xmake.lua</code>.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">is_option</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span> <span class="k">then</span>
    <span class="n">add_subdirs</span><span class="p">(</span><span class="s2">"src/demo"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h4 id="global-interfaces">Global Interfaces</h4>

<p>The global interface affects the whole project description scope and all sub-project files.</p>

<table>
  <thead>
    <tr>
      <th>Interfaces</th>
      <th>Description</th>
      <th>Version</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#includes">includes</a></td>
      <td>Add sub-project files and directories</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#set_modes">set_modes</a></td>
      <td>Set project compilation modes</td>
      <td>&gt;= 2.1.2</td>
    </tr>
    <tr>
      <td><a href="#set_project">set_project</a></td>
      <td>Set project name</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#set_version">set_version</a></td>
      <td>Set project version</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#set_xmakever">set_xmakever</a></td>
      <td>Set minimal xmake version</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#add_subdirs">add_subdirs</a></td>
      <td>Add sub-project directories</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#add_subfiles">add_subfiles</a></td>
      <td>Add sub-project files</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#add_moduledirs">add_moduledirs</a></td>
      <td>Add module directories</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#add_plugindirs">add_plugindirs</a></td>
      <td>Add plugin directories</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#add_packagedirs">add_packagedirs</a></td>
      <td>Add package directories</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h5 id="includes">includes</h5>

<h6 id="add-sub-project-files-and-directories">Add sub-project files and directories</h6>

<p>It is used to replace <a href="#add_subdirs">add_subdirs</a> and <a href="#add_subfiles">add_subfiles</a>.</p>

<h5 id="set_modes">set_modes</h5>

<h6 id="set-project-compilation-modes">Set project compilation modes</h6>

<p>This is an optional api, just to make it easy for the plugin to get mode configuration information now.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">set_modes</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">,</span> <span class="s2">"release"</span><span class="p">)</span>
</code></pre>
</div>

<p>If you set this configuration, you need not set them manually when generating vs201x project.</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake project -k vs2017
</code></pre>
</div>

<p>Otherwise, you need to run:</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake project -k vs2017 -m <span class="s2">"debug,release"</span>
</code></pre>
</div>

<p class="tip">
If you do not set this configuration, [is_mode](#is_mode) can also be used normally.
</p>

<h5 id="set_project">set_project</h5>

<h6 id="set-project-name">Set project name</h6>

<p>Set the whole project name, we can set it at the beginning of <code class="highlighter-rouge">xmake.lua</code>.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- set project name</span>
<span class="n">set_project</span><span class="p">(</span><span class="s2">"tbox"</span><span class="p">)</span>

<span class="c1">-- set project version</span>
<span class="n">set_version</span><span class="p">(</span><span class="s2">"1.5.1"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="set_version">set_version</h5>

<h6 id="set-project-version">Set project version</h6>

<p>Set the whole project version, we can set it at the beginning of <code class="highlighter-rouge">xmake.lua</code>.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">set_version</span><span class="p">(</span><span class="s2">"1.5.1"</span><span class="p">)</span>
</code></pre>
</div>

<p>It will add project version info to this file automatically if we call <a href="#targetset_config_header">set_config_header</a> to set <code class="highlighter-rouge">config.h</code>.`</p>

<p>For example:</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="c1">// version
</span><span class="cp">#define TB_CONFIG_VERSION "1.5.1"
#define TB_CONFIG_VERSION_MAJOR 1
#define TB_CONFIG_VERSION_MINOR 5
#define TB_CONFIG_VERSION_ALTER 1
#define TB_CONFIG_VERSION_BUILD 201510220917
</span></code></pre>
</div>

<p>We can set build version in v2.1.7 version:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">set_version</span><span class="p">(</span><span class="s2">"1.5.1"</span><span class="p">,</span> <span class="p">{</span><span class="n">build</span> <span class="o">=</span> <span class="s2">"%Y%m%d%H%M"</span><span class="p">})</span>
</code></pre>
</div>

<h5 id="set_xmakever">set_xmakever</h5>

<h6 id="set-minimal-xmake-version">Set minimal xmake version</h6>

<p>If the current xmake version less than the required version, it will prompt an error.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- the current xmake version must be larger than 2.1.0</span>
<span class="n">set_xmakever</span><span class="p">(</span><span class="s2">"2.1.0"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="add_subdirs">add_subdirs</h5>

<h6 id="add-sub-project-directories">Add sub-project directories</h6>

<p>This interface will add an sub-project directories to the current <code class="highlighter-rouge">xmake.lua</code>, it will load the <code class="highlighter-rouge">xmake.lua</code> file of the sub-directories.</p>

<p>For example, we have a following project directory tree:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>./tbox
├── src
│   ├── demo
│   │   └── xmake.lua
│   └── tbox
│       └── xmake.lua
└── xmake.lua
</code></pre>
</div>

<p>We can add sub-project <code class="highlighter-rouge">tbox</code> and <code class="highlighter-rouge">demo</code> directories to the root <code class="highlighter-rouge">xmake.lua</code>.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_subdirs</span><span class="p">(</span><span class="s2">"src/tbox"</span><span class="p">)</span> 
<span class="k">if</span> <span class="n">is_option</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span> <span class="k">then</span> 
    <span class="n">add_subdirs</span><span class="p">(</span><span class="s2">"src/demo"</span><span class="p">)</span> 
<span class="k">end</span>
</code></pre>
</div>

<p>By default, xmake will compile all the targets, if you only want to compile the specified target, you can do:</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="c"># only build `tbox` target</span>
<span class="gp">$ </span>xmake build tbox
</code></pre>
</div>

<h5 id="add_subfiles">add_subfiles</h5>

<h6 id="add-sub-project-files">Add sub-project files</h6>

<p><code class="highlighter-rouge">add_subfiles</code> is simular to <a href="#add_subdirs">add_subdirs</a>.</p>

<p>The only difference is that this interface specifies the path where the ‘xmake.lua’ file directly, rather than a directory.</p>

<p>for example:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_subfiles</span><span class="p">(</span><span class="s2">"src/tbox/xmake.lua"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="add_moduledirs">add_moduledirs</h5>

<h6 id="add-module-directories">Add module directories</h6>

<p>The builtin modules are placed in the ‘xmake/modules’ directory, but for some user-defined modules for a specific project, you can configure additional module directory is specified in the ‘xmake.lua`.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_moduledirs</span><span class="p">(</span><span class="s2">"$(projectdir)/modules"</span><span class="p">)</span>
</code></pre>
</div>
<p>xmake will load the given module in the given directory when calling <code class="highlighter-rouge">import</code>.</p>

<h5 id="add_plugindirs">add_plugindirs</h5>

<h6 id="add-plugin-directories">Add plugin directories</h6>

<p>The builtin plugins are placed in the ‘xmake/plugins’ directory, but for some user-defined plugins for a specific project, you can configure additional plugin directory is specified in the ‘xmake.lua`.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_plugindirs</span><span class="p">(</span><span class="s2">"$(projectdir)/plugins"</span><span class="p">)</span>
</code></pre>
</div>
<p>xmake will load all plugins in the given directory.</p>

<h5 id="add_packagedirs">add_packagedirs</h5>

<h6 id="add-package-directories">Add package directories</h6>

<p>By setting up a dependency package directory, you can easily integrate some third-party dependent libraries, 
taking the tbox project as an example, and its package directory is as follows:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>tbox.pkg
- base.pkg
- zlib.pkg
- polarssl.pkg
- openssl.pkg
- mysql.pkg
- pcre.pkg
- ...
</code></pre>
</div>

<p>If you want the current project to load these packages, first specify the package directory path, for example:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_packagedirs</span><span class="p">(</span><span class="s2">"pkg"</span><span class="p">)</span>
</code></pre>
</div>

<p>Then, please add these packages to the given target by <a href="#add_packages">add_packages</a>:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"tbox"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"polarssl"</span><span class="p">,</span> <span class="s2">"pcre"</span><span class="p">,</span> <span class="s2">"mysql"</span><span class="p">)</span>
</code></pre>
</div>

<p>xmake will check these packages automatically and link them if exists, and we can disable them manually.</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f --openssl<span class="o">=</span>n
</code></pre>
</div>

<h4 id="project-target">Project Target</h4>

<p>We can use <code class="highlighter-rouge">target("test")</code> to define a project target named “test”, each target generates an executable program, a static library, or a dynamic library.</p>

<p class="tip">
All interfaces of target can be set in the global scope, which affects all sub-targets.
</p>

<p>For example:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- affects both test and test2 targets</span>
<span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
`target()' interface can be repeatedly invoked in different places to set the same target.
</p>

<table>
  <thead>
    <tr>
      <th>Interfaces</th>
      <th>Description</th>
      <th>Support version</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#target">target</a></td>
      <td>Define a project target</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#target_end">target_end</a></td>
      <td>End target definition</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_kind">set_kind</a></td>
      <td>Set target kind</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_strip">set_strip</a></td>
      <td>Strip target symbols</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_default">set_default</a></td>
      <td>Mark as default target</td>
      <td>&gt;= 2.1.3</td>
    </tr>
    <tr>
      <td><a href="#targetset_options">set_options</a></td>
      <td>Set configuartion options</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_symbols">set_symbols</a></td>
      <td>Set symbol info</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_basename">set_basename</a></td>
      <td>Set the base name for target file</td>
      <td>&gt;= 2.1.2</td>
    </tr>
    <tr>
      <td><a href="#targetset_warnings">set_warnings</a></td>
      <td>Set compilation warning level</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_optimize">set_optimize</a></td>
      <td>Set compilation optimization level</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_languages">set_languages</a></td>
      <td>Set source code language standards</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_headerdir">set_headerdir</a></td>
      <td>Set output directories for header files</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_targetdir">set_targetdir</a></td>
      <td>Set output directories for target file</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_objectdir">set_objectdir</a></td>
      <td>Set output directories for object files</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_imports">add_imports</a></td>
      <td>Add imported modules for the custom script</td>
      <td>&gt;= 2.1.7</td>
    </tr>
    <tr>
      <td><a href="#targetadd_rules">add_rules</a></td>
      <td>Add custom compilation rule to target</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#targeton_load">on_load</a></td>
      <td>Run custom load target configuartion script</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#targeton_build">on_build</a></td>
      <td>Run custom build target script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targeton_clean">on_clean</a></td>
      <td>Run custom clean files script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targeton_package">on_package</a></td>
      <td>Run custom package target script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targeton_install">on_install</a></td>
      <td>Run custom install target file script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targeton_uninstall">on_uninstall</a></td>
      <td>Run custom uninstall target file script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targeton_run">on_run</a></td>
      <td>Run custom run target script</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_build">before_build</a></td>
      <td>Run custom script before building target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_clean">before_clean</a></td>
      <td>Run custom script before cleaning target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_package">before_package</a></td>
      <td>Run custom script before packaging target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_install">before_install</a></td>
      <td>Run custom script before installing target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_uninstall">before_uninstall</a></td>
      <td>Run custom script before uninstalling target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetbefore_run">before_run</a></td>
      <td>Run custom script before running target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_build">after_build</a></td>
      <td>Run custom script after building target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_clean">after_clean</a></td>
      <td>Run custom script after cleaning target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_package">after_package</a></td>
      <td>Run custom script after packaging target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_install">after_install</a></td>
      <td>Run custom script after installing target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_uninstall">after_uninstall</a></td>
      <td>Run custom script after uninstalling target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetafter_run">after_run</a></td>
      <td>Run custom script after running target</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_config_h">set_config_h</a></td>
      <td>Set auto-generated config header file</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5 deprecated</td>
    </tr>
    <tr>
      <td><a href="#targetset_config_h">set_config_h_prefix</a></td>
      <td>Set macro prefix in auto-generated config header</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5 deprecated</td>
    </tr>
    <tr>
      <td><a href="#targetset_config_header">set_config_header</a></td>
      <td>Set auto-generated config header file (new)</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#targetset_pcheader">set_pcheader</a></td>
      <td>Set pre-compiled c header file</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#targetset_pcxxheader">set_pcxxheader</a></td>
      <td>Set pre-compiled c++ header file</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#targetadd_deps">add_deps</a></td>
      <td>Add target dependencies</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_links">add_links</a></td>
      <td>Add link libraries</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_files">add_files</a></td>
      <td>Add source files</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetdel_files">del_files</a></td>
      <td>Remove source files</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#targetadd_headers">add_headers</a></td>
      <td>Add installed header files</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_linkdirs">add_linkdirs</a></td>
      <td>Add link search directories</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_rpathdirs">add_rpathdirs</a></td>
      <td>Add load search directories for dynamic library</td>
      <td>&gt;= 2.1.3</td>
    </tr>
    <tr>
      <td><a href="#targetadd_includedirs">add_includedirs</a></td>
      <td>Add include search directories</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_defines">add_defines</a></td>
      <td>Add macro definition</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_undefines">add_undefines</a></td>
      <td>Add macro undefinition</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_defines_h">add_defines_h</a></td>
      <td>Add macro definition to auto-generated config header</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_undefines_h">add_undefines_h</a></td>
      <td>Add macro undefinition to auto-generated config header</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cflags">add_cflags</a></td>
      <td>Add c compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxflags">add_cxflags</a></td>
      <td>Add c/c++ compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxxflags">add_cxxflags</a></td>
      <td>Add c++ compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mflags">add_mflags</a></td>
      <td>Add objc compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mxflags">add_mxflags</a></td>
      <td>Add objc/objc++ compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mxxflags">add_mxxflags</a></td>
      <td>Add objc++ compilation flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_scflags">add_scflags</a></td>
      <td>Add swift compilation flags</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_asflags">add_asflags</a></td>
      <td>Add asm compilation flags</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_gcflags">add_gcflags</a></td>
      <td>Add go compilation flags</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_dcflags">add_dcflags</a></td>
      <td>Add dlang compilation flags</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_rcflags">add_rcflags</a></td>
      <td>Add rust compilation flags</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_ldflags">add_ldflags</a></td>
      <td>Add static library link flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_arflags">add_arflags</a></td>
      <td>Add archive library flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_shflags">add_shflags</a></td>
      <td>Add dynamic library link flags</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cfunc">add_cfunc</a></td>
      <td>Add single c function for checking</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxxfunc">add_cxxfunc</a></td>
      <td>Add single c++ function for checking</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cfuncs">add_cfuncs</a></td>
      <td>Add c functions for checking</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxxfuncs">add_cxxfuncs</a></td>
      <td>Add c++ functions for checking</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_packages">add_packages</a></td>
      <td>Add package dependencies</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_options">add_options</a></td>
      <td>Add options dependencies</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_languages">add_languages</a></td>
      <td>Add language standards</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_vectorexts">add_vectorexts</a></td>
      <td>Add vector extensions</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_frameworks">add_frameworks</a></td>
      <td>Add frameworks</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_frameworkdirs">add_frameworkdirs</a></td>
      <td>Add framework search directories</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h5 id="target">target</h5>

<h6 id="define-a-project-target">Define a project target</h6>

<p>Defines a console target named <code class="highlighter-rouge">test</code> in project and the default target filename is <code class="highlighter-rouge">test</code>.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
</code></pre>
</div>

<p>And we can call <code class="highlighter-rouge">target("demo")</code> repeatly to enter the target scope for modifying it’s configuartion.</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- defines target: demo and enter it's scope to set configuartion</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/demo.c"</span><span class="p">)</span>

<span class="c1">-- defines and set `other` target</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"other"</span><span class="p">)</span>
    <span class="o">...</span>

<span class="c1">-- re-enter demo target scope and add file `test.c` to `demo`</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test.c"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
All configuartion in root scope affects all targets, but does not affect the configuartion of `option()`.
</p>

<p>For example:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>                   <span class="c1">-- add -DDEBUG</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/demo.c"</span><span class="p">)</span> 

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>                   <span class="c1">-- add -DDEBUG</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test.c"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="target_end">target_end</h5>

<h6 id="end-target-definition">End target definition</h6>

<p class="warning">
Translating ..., help me please! [Edit this page](https://github.com/xmake-io/xmake/blob/master/docs/manual.md)
</p>

<p>这是一个可选的api，如果不调用，那么<code class="highlighter-rouge">target("xxx")</code>之后的所有设置都是针对这个target进行的，除非进入其他<code class="highlighter-rouge">target</code>, <code class="highlighter-rouge">option</code>, <code class="highlighter-rouge">task</code>域。</p>

<p>如果想设置完当前<code class="highlighter-rouge">target</code>后，显示离开<code class="highlighter-rouge">target</code>域，进入根域设置，那么可以通过这个api才操作，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
<span class="n">target_end</span><span class="p">()</span>

<span class="c1">-- 此处已在根域</span>
<span class="c1">-- ...</span>
</code></pre>
</div>

<p>如果不调用这个api的话:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>

<span class="c1">-- 此处还在上面target域中，之后的设置还是针对test进行的设置</span>
<span class="c1">-- ...</span>

<span class="c1">-- 这个时候才离开test，进入另外一个target域中</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="o">...</span>
</code></pre>
</div>

<h5 id="targetset_kind">target:set_kind</h5>

<h6 id="set-target-kind">Set target kind</h6>

<p>设置目标类型，目前支持的类型有：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>binary</td>
      <td>二进制程序</td>
    </tr>
    <tr>
      <td>static</td>
      <td>静态库程序</td>
    </tr>
    <tr>
      <td>shared</td>
      <td>动态库程序</td>
    </tr>
  </tbody>
</table>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetset_strip">target:set_strip</h5>

<h6 id="strip-target-symbols">Strip target symbols</h6>

<p>设置当前目标的strip模式，目前支持一下模式：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>debug</td>
      <td>链接的时候，strip掉调试符号</td>
    </tr>
    <tr>
      <td>all</td>
      <td>链接的时候，strip掉所有符号，包括调试符号</td>
    </tr>
  </tbody>
</table>

<p>这个api一般在release模式下使用，可以生成更小的二进制程序。。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="n">set_strip</span><span class="p">(</span><span class="s2">"all"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
这个api不一定非得在target之后使用，如果没有target指定，那么将会设置到全局模式。。
</p>

<h5 id="targetset_default">target:set_default</h5>

<h6 id="mark-as-default-target">Mark as default target</h6>

<p>这个接口用于设置给定工程目标是否作为默认构建，如果没有调用此接口进行设置，那么这个目标就是默认被构建的，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test3"</span><span class="p">)</span>
    <span class="o">...</span>
</code></pre>
</div>

<p>上述代码的三个目标，在执行<code class="highlighter-rouge">xmake</code>, <code class="highlighter-rouge">xmake install</code>, <code class="highlighter-rouge">xmake package</code>, <code class="highlighter-rouge">xmake run</code>等命令的时候，如果不指定目标名，那么：</p>

<table>
  <thead>
    <tr>
      <th>目标名</th>
      <th>行为</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>test1</td>
      <td>不会被默认构建、安装、打包和运行</td>
    </tr>
    <tr>
      <td>test2</td>
      <td>默认构建、安装、打包和运行</td>
    </tr>
    <tr>
      <td>test3</td>
      <td>默认构建、安装、打包和运行</td>
    </tr>
  </tbody>
</table>

<p>通过上面的例子，可以看到默认目标可以设置多个，运行的时候也会依次运行。</p>

<p class="tip">
    需要注意的是，`xmake uninstall`和`xmake clean`命令不受此接口设置影响，因为用户大部分情况下都是喜欢清除和卸载所有。
</p>

<p>如果不想使用默认的目标，那么可以手动指定需要构建安装的目标：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake build targetname
<span class="gp">$ </span>xmake install targetname
</code></pre>
</div>

<p>如果要强制构建安装所有目标，可以传入<code class="highlighter-rouge">[-a|--all]</code>参数：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake build <span class="o">[</span>-a|--all]
<span class="gp">$ </span>xmake install <span class="o">[</span>-a|--all]
</code></pre>
</div>

<h5 id="targetset_options">target:set_options</h5>

<h6 id="set-configuartion-options">Set configuartion options</h6>

<p>添加选项依赖，如果通过<a href="#option">option</a>接口自定义了一些选项，那么只有在指定<code class="highlighter-rouge">target</code>目标域下，添加此选项，才能进行关联生效。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个hello选项</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"HELLO_ENABLE"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- 如果hello选项被启用了，这个时候就会将-DHELLO_ENABLE宏应用到test目标上去</span>
    <span class="n">set_options</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
只有调用`set_options`进行关联生效后，[option](#option) 中定义的一些设置才会影响到此`target`目标，例如：宏定义、链接库、编译选项等等
</p>

<h5 id="targetset_symbols">target:set_symbols</h5>

<h6 id="set-symbol-info">Set symbol info</h6>

<p>设置目标的符号模式，如果当前没有定义target，那么将会设置到全局状态中，影响所有后续的目标。</p>

<p>目前主要支持一下几个级别：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>debug</td>
      <td>添加调试符号</td>
    </tr>
    <tr>
      <td>hidden</td>
      <td>设置符号不可见</td>
    </tr>
  </tbody>
</table>

<p>这两个值也可以同时被设置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 添加调试符号, 设置符号不可见</span>
<span class="n">set_symbols</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">,</span> <span class="s2">"hidden"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果没有调用这个api，默认是禁用调试符号的。。</p>

<h5 id="targetset_basename">target:set_basename</h5>

<h6 id="set-the-base-name-for-target-file">Set the base name for target file</h6>

<p>默认情况下，生成的目标文件名基于<code class="highlighter-rouge">target("name")</code>中配置的值，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 目标文件名为：libxxx.a</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>

<span class="c1">-- 目标文件名为：libxxx2.so</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"xxx2"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">)</span>
</code></pre>
</div>

<p>默认的命名方式，基本上可以满足大部分情况下的需求，但是如果有时候想要更加定制化目标文件名</p>

<p>例如，按编译模式和架构区分目标名，这个时候可以使用这个接口，来设置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">set_basename</span><span class="p">(</span><span class="s2">"xxx_$(mode)_$(arch)"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果这个时候，编译配置为：<code class="highlighter-rouge">xmake f -m debug -a armv7</code>，那么生成的文件名为：<code class="highlighter-rouge">libxxx_debug_armv7.a</code></p>

<p>如果还想进一步定制目标文件的目录名，可参考：<a href="#targetset_targetdir">set_targetdir</a>。</p>

<p>或者通过编写自定义脚本，实现更高级的逻辑，具体见：<a href="#targetafter_build">after_build</a>和<a href="#os-mv">os.mv</a>。</p>

<h5 id="targetset_warnings">target:set_warnings</h5>

<h6 id="set-compilation-warning-level">Set compilation warning level</h6>

<p>设置当前目标的编译的警告级别，一般支持一下几个级别：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
      <th>gcc/clang</th>
      <th>msvc</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>none</td>
      <td>禁用所有警告</td>
      <td>-w</td>
      <td>-W0</td>
    </tr>
    <tr>
      <td>less</td>
      <td>启用较少的警告</td>
      <td>-W1</td>
      <td>-W1</td>
    </tr>
    <tr>
      <td>more</td>
      <td>启用较多的警告</td>
      <td>-W3</td>
      <td>-W3</td>
    </tr>
    <tr>
      <td>all</td>
      <td>启用所有警告</td>
      <td>-Wall</td>
      <td>-W3 (-Wall too more warnings)</td>
    </tr>
    <tr>
      <td>error</td>
      <td>将所有警告作为编译错误</td>
      <td>-Werror</td>
      <td>-WX</td>
    </tr>
  </tbody>
</table>

<p>这个api的参数是可以混合添加的，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 启用所有警告，并且作为编译错误处理</span>
<span class="n">set_warnings</span><span class="p">(</span><span class="s2">"all"</span><span class="p">,</span> <span class="s2">"error"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果当前没有目标，调用这个api将会设置到全局模式。。</p>

<h5 id="targetset_optimize">target:set_optimize</h5>

<h6 id="set-compilation-optimization-level">Set compilation optimization level</h6>

<p>设置目标的编译优化等级，如果当前没有设置目标，那么将会设置到全局状态中，影响所有后续的目标。</p>

<p>目前主要支持一下几个级别：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
      <th>gcc/clang</th>
      <th>msvc</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>none</td>
      <td>禁用优化</td>
      <td>-O0</td>
      <td>-Od</td>
    </tr>
    <tr>
      <td>fast</td>
      <td>快速优化</td>
      <td>-O1</td>
      <td>default</td>
    </tr>
    <tr>
      <td>faster</td>
      <td>更快的优化</td>
      <td>-O2</td>
      <td>-Ox</td>
    </tr>
    <tr>
      <td>fastest</td>
      <td>最快运行速度的优化</td>
      <td>-O3</td>
      <td>-Ox -fp:fast</td>
    </tr>
    <tr>
      <td>smallest</td>
      <td>最小化代码优化</td>
      <td>-Os</td>
      <td>-O1</td>
    </tr>
    <tr>
      <td>aggressive</td>
      <td>过度优化</td>
      <td>-Ofast</td>
      <td>-Ox -fp:fast</td>
    </tr>
  </tbody>
</table>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 最快运行速度的优化</span>
<span class="n">set_optimize</span><span class="p">(</span><span class="s2">"fastest"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetset_languages">target:set_languages</h5>

<h6 id="set-source-code-language-standards">Set source code language standards</h6>

<p>设置目标代码编译的语言标准，如果当前没有目标存在，将会设置到全局模式中。。。</p>

<p>支持的语言标准目前主要有以下几个：</p>

<table>
  <thead>
    <tr>
      <th>值</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>ansi</td>
      <td>c语言标准: ansi</td>
    </tr>
    <tr>
      <td>c89</td>
      <td>c语言标准: c89</td>
    </tr>
    <tr>
      <td>gnu89</td>
      <td>c语言标准: gnu89</td>
    </tr>
    <tr>
      <td>c99</td>
      <td>c语言标准: c99</td>
    </tr>
    <tr>
      <td>gnu99</td>
      <td>c语言标准: gnu99</td>
    </tr>
    <tr>
      <td>cxx98</td>
      <td>c++语言标准: <code class="highlighter-rouge">c++98</code></td>
    </tr>
    <tr>
      <td>gnuxx98</td>
      <td>c++语言标准: <code class="highlighter-rouge">gnu++98</code></td>
    </tr>
    <tr>
      <td>cxx11</td>
      <td>c++语言标准: <code class="highlighter-rouge">c++11</code></td>
    </tr>
    <tr>
      <td>gnuxx11</td>
      <td>c++语言标准: <code class="highlighter-rouge">gnu++11</code></td>
    </tr>
    <tr>
      <td>cxx14</td>
      <td>c++语言标准: <code class="highlighter-rouge">c++14</code></td>
    </tr>
    <tr>
      <td>gnuxx14</td>
      <td>c++语言标准: <code class="highlighter-rouge">gnu++14</code></td>
    </tr>
    <tr>
      <td>cxx1z</td>
      <td>c++语言标准: <code class="highlighter-rouge">c++1z</code></td>
    </tr>
    <tr>
      <td>gnuxx1z</td>
      <td>c++语言标准: <code class="highlighter-rouge">gnu++1z</code></td>
    </tr>
    <tr>
      <td>cxx17</td>
      <td>c++语言标准: <code class="highlighter-rouge">c++17</code></td>
    </tr>
    <tr>
      <td>gnuxx17</td>
      <td>c++语言标准: <code class="highlighter-rouge">gnu++17</code></td>
    </tr>
  </tbody>
</table>

<p>c标准和c++标准可同时进行设置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 设置c代码标准：c99， c++代码标准：c++11</span>
<span class="n">set_languages</span><span class="p">(</span><span class="s2">"c99"</span><span class="p">,</span> <span class="s2">"cxx11"</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
并不是设置了指定的标准，编译器就一定会按这个标准来编译，毕竟每个编译器支持的力度不一样，但是xmake会尽最大可能的去适配当前编译工具的支持标准。。。
<br /><br />
例如：
<br />
windows下vs的编译器并不支持按c99的标准来编译c代码，只能支持到c89，但是xmake为了尽可能的支持它，所以在设置c99的标准后，xmake会强制按c++代码模式去编译c代码，从一定程度上解决了windows下编译c99的c代码问题。。
用户不需要去额外做任何修改。。
</p>

<h5 id="targetset_headerdir">target:set_headerdir</h5>

<h6 id="set-output-directories-for-header-files">Set output directories for header files</h6>

<p>设置头文件的输出目录，默认输出到build目录中。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_headerdir</span><span class="p">(</span><span class="s2">"$(buildir)/include"</span><span class="p">)</span>
</code></pre>
</div>

<p>对于需要安装哪些头文件，可参考<a href="#targetadd_headers">add_headers</a>接口。</p>

<h5 id="targetset_targetdir">target:set_targetdir</h5>

<h6 id="set-output-directories-for-target-files">Set output directories for target files</h6>

<p>设置目标程序文件的输出目录，一般情况下，不需要设置，默认会输出在build目录下</p>

<p>而build的目录可以在工程配置的时候，手动修改：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code>xmake f -o /tmp/build
</code></pre>
</div>

<p>修改成<code class="highlighter-rouge">/tmp/build</code>后，目标文件默认输出到<code class="highlighter-rouge">/tmp/build</code>下面。</p>

<p>而如果用这个接口去设置，就不需要每次敲命令修改了，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_targetdir</span><span class="p">(</span><span class="s2">"/tmp/build"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
如果显示设置了`set_targetdir`， 那么优先选择`set_targetdir`指定的目录为目标文件的输出目录。
</p>

<h5 id="targetset_objectdir">target:set_objectdir</h5>

<h6 id="set-output-directories-for-object-files">Set output directories for object files</h6>

<p>设置目标target的对象文件(<code class="highlighter-rouge">*.o/obj</code>)的输出目录，例如:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_objectdir</span><span class="p">(</span><span class="s2">"$(buildir)/.objs"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_imports">target:add_imports</h5>

<h6 id="add-imported-modules-for-the-custom-script">Add imported modules for the custom script</h6>

<p>通常，我们在<a href="#targeton_build">on_build</a>等自定义脚本内部，可以通过<code class="highlighter-rouge">import("core.base.task")</code>的方式导入扩展模块，
但是对于自定义脚本比较多的情况下，每个自定义脚本都重复导入一遍，非常的繁琐，那么可以通过这个接口，实现预先导入，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.project"</span><span class="p">)</span>

        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.project"</span><span class="p">)</span>
        
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.project"</span><span class="p">)</span>
        
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>通过此接口可以简化为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_imports</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">,</span> <span class="s2">"core.project.project"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_rules">target:add_rules</h5>

<h6 id="add-custom-compilation-rule-to-target">Add custom compilation rule to target</h6>

<p>我们可以通过预先设置规则支持的文件后缀，来扩展其他文件的构建支持：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个markdown文件的构建规则</span>
<span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".md"</span><span class="p">,</span> <span class="s2">".markdown"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetdir</span><span class="p">(),</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">)</span> <span class="o">..</span> <span class="s2">".html"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    
    <span class="c1">-- 使test目标支持markdown文件的构建规则</span>
    <span class="n">add_rules</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>

    <span class="c1">-- 添加markdown文件的构建</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.md"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.markdown"</span><span class="p">)</span>
</code></pre>
</div>

<p>我们也可以指定应用局部文件到规则，具体使用见：<a href="#targetadd_files">add_files</a>。</p>

<h5 id="targeton_load">target:on_load</h5>

<h6 id="run-custom-load-target-configuartion-script">Run custom load target configuartion script</h6>

<p>在target初始化加载的时候，将会执行此脚本，在里面可以做一些动态的目标配置，实现更灵活的目标描述定义，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"defines"</span><span class="p">,</span> <span class="s2">"DEBUG"</span><span class="p">,</span> <span class="s2">"TEST=\"</span><span class="n">hello</span><span class="err">\</span><span class="s2">""</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"linkdirs"</span><span class="p">,</span> <span class="s2">"/usr/lib"</span><span class="p">,</span> <span class="s2">"/usr/local/lib"</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">({</span><span class="n">includedirs</span> <span class="o">=</span> <span class="s2">"/usr/include"</span><span class="p">,</span> <span class="s2">"links"</span> <span class="o">=</span> <span class="s2">"pthread"</span><span class="p">})</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>可以在<code class="highlighter-rouge">on_load</code>里面，通过<code class="highlighter-rouge">target:set</code>, <code class="highlighter-rouge">target:add</code> 来动态添加各种target属性。</p>

<h5 id="targeton_build">target:on_build</h5>

<h6 id="run-custom-build-target-script">Run custom build target script</h6>

<p>覆盖target目标默认的构建行为，实现自定义的编译过程，一般情况下，并不需要这么做，除非确实需要做一些xmake默认没有提供的编译操作。</p>

<p>你可以通过下面的方式覆盖它，来自定义编译操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义编译脚本</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build it"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：2.1.5版本之后，所有target的自定义脚本都可以针对不同平台和架构，分别处理，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="s2">"iphoneos|arm*"</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build for iphoneos and arm"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>其中如果第一个参数为字符串，那么就是指定这个脚本需要在哪个<code class="highlighter-rouge">平台|架构</code>下，才会被执行，并且支持模式匹配，例如<code class="highlighter-rouge">arm*</code>匹配所有arm架构。</p>

<p>当然也可以只设置平台，不设置架构，这样就是匹配指定平台下，执行脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="s2">"windows"</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build for windows"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
一旦对这个target目标设置了自己的build过程，那么xmake默认的构建过程将不再被执行。
</p>

<h5 id="targeton_clean">target:on_clean</h5>

<h6 id="run-custom-clean-files-script">Run custom clean files script</h6>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [c|clean}</code>的清理操作，实现自定义清理过程。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义清理脚本</span>
    <span class="n">on_clean</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="c1">-- 仅删掉目标文件</span>
        <span class="n">os</span><span class="p">.</span><span class="n">rm</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>一些target接口描述如下：</p>

<table>
  <thead>
    <tr>
      <th>target接口</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>target:name()</td>
      <td>获取目标名</td>
    </tr>
    <tr>
      <td>target:targetfile()</td>
      <td>获取目标文件路径</td>
    </tr>
    <tr>
      <td>target:get(“kind”)</td>
      <td>获取目标的构建类型</td>
    </tr>
    <tr>
      <td>target:get(“defines”)</td>
      <td>获取目标的宏定义</td>
    </tr>
    <tr>
      <td>target:get(“xxx”)</td>
      <td>其他通过 <code class="highlighter-rouge">set_/add_</code>接口设置的target信息，都可以通过此接口来获取</td>
    </tr>
    <tr>
      <td>target:add(“links”, “pthread”)</td>
      <td>添加目标设置</td>
    </tr>
    <tr>
      <td>target:set(“links”, “pthread”, “z”)</td>
      <td>覆写目标设置</td>
    </tr>
    <tr>
      <td>target:deps()</td>
      <td>获取目标的所有依赖目标</td>
    </tr>
    <tr>
      <td>target:dep(“depname”)</td>
      <td>获取指定的依赖目标</td>
    </tr>
    <tr>
      <td>target:sourcebatches()</td>
      <td>获取目标的所有源文件列表</td>
    </tr>
  </tbody>
</table>

<h5 id="targeton_package">target:on_package</h5>

<h6 id="run-custom-package-target-script">Run custom package target script</h6>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [p|package}</code>的打包操作，实现自定义打包过程，如果你想对指定target打包成自己想要的格式，可以通过这个接口自定义它。</p>

<p>这个接口还是挺实用的，例如，编译玩jni后，将生成的so，打包进apk包中。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个android app的测试demo</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>

    <span class="c1">-- 生成动态库：libdemo.so</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">)</span>

    <span class="c1">-- 设置对象的输出目录，可选</span>
    <span class="n">set_objectdir</span><span class="p">(</span><span class="s2">"$(buildir)/.objs"</span><span class="p">)</span>

    <span class="c1">-- 每次编译完的libdemo.so的生成目录，设置为app/libs/armeabi</span>
    <span class="n">set_targetdir</span><span class="p">(</span><span class="s2">"libs/armeabi"</span><span class="p">)</span>

    <span class="c1">-- 添加jni的代码文件</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"jni/*.c"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义打包脚本，在使用xmake编译完libdemo.so后，执行xmake p进行打包</span>
    <span class="c1">-- 会自动使用ant将app编译成apk文件</span>
    <span class="c1">--</span>
    <span class="n">on_package</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="c1">-- 使用ant编译app成apk文件，输出信息重定向到日志文件</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ant debug"</span><span class="p">)</span> 
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targeton_install">target:on_install</h5>

<h6 id="run-custom-install-target-file-script">Run custom install target file script</h6>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [i|install}</code>的安装操作，实现自定义安装过程。</p>

<p>例如，将生成的apk包，进行安装。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义安装脚本，自动安装apk文件</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="c1">-- 使用adb安装打包生成的apk文件</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb install -r ./bin/Demo-debug.apk"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targeton_uninstall">target:on_uninstall</h5>

<h6 id="run-custom-uninstall-target-file-script">Run custom uninstall target file script</h6>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [u|uninstall}</code>的卸载操作，实现自定义卸载过程。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_uninstall</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="o">...</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targeton_run">target:on_run</h5>

<h6 id="run-custom-run-target-script">Run custom run target script</h6>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [r|run}</code>的运行操作，实现自定义运行过程。</p>

<p>例如，运行安装好的apk程序：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义运行脚本，自动运行安装好的app程序，并且自动获取设备输出信息</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb shell am start -n com.demo/com.demo.DemoTest"</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb logcat"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_build">target:before_build</h5>

<h6 id="run-custom-script-before-building-target">Run custom script before building target</h6>

<p>并不会覆盖默认的构建操作，只是在构建之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_clean">target:before_clean</h5>

<h6 id="run-custom-script-before-cleaning-target">Run custom script before cleaning target</h6>

<p>并不会覆盖默认的清理操作，只是在清理之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_clean</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_package">target:before_package</h5>

<h6 id="run-custom-script-before-packaging-target">Run custom script before packaging target</h6>

<p>并不会覆盖默认的打包操作，只是在打包之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_package</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_install">target:before_install</h5>

<h6 id="run-custom-script-before-installing-target">Run custom script before installing target</h6>

<p>并不会覆盖默认的安装操作，只是在安装之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_uninstall">target:before_uninstall</h5>

<h6 id="run-custom-script-before-uninstalling-target">Run custom script before uninstalling target</h6>

<p>并不会覆盖默认的卸载操作，只是在卸载之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_uninstall</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetbefore_run">target:before_run</h5>

<h6 id="run-custom-script-before-running-target">Run custom script before running target</h6>

<p>并不会覆盖默认的运行操作，只是在运行之前增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetafter_build">target:after_build</h5>

<h6 id="run-custom-script-after-building-target">Run custom script after building target</h6>

<p>并不会覆盖默认的构建操作，只是在构建之后增加一些自定义的操作。</p>

<p>例如，对于ios的越狱开发，构建完程序后，需要用<code class="highlighter-rouge">ldid</code>进行签名操作</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ldid -S %s"</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetafter_clean">target:after_clean</h5>

<h6 id="run-custom-script-after-cleaning-target">Run custom script after cleaning target</h6>

<p>并不会覆盖默认的清理操作，只是在清理之后增加一些自定义的操作。</p>

<p>一般可用于清理编译某target自动生成的一些额外的临时文件，这些文件xmake默认的清理规则可能没有清理到，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_clean</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">rm</span><span class="p">(</span><span class="s2">"$(buildir)/otherfiles"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetafter_package">target:after_package</h5>

<h6 id="run-custom-script-after-packaging-target">Run custom script after packaging target</h6>

<p>并不会覆盖默认的打包操作，只是在打包之后增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_package</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetafter_install">target:after_install</h5>

<h6 id="run-custom-script-after-installing-target">Run custom script after installing target</h6>

<p>并不会覆盖默认的安装操作，只是在安装之后增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>
<h5 id="targetafter_uninstall">target:after_uninstall</h5>

<h6 id="run-custom-script-after-uninstalling-target">Run custom script after uninstalling target</h6>

<p>并不会覆盖默认的卸载操作，只是在卸载之后增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_uninstall</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetafter_run">target:after_run</h5>

<h6 id="run-custom-script-after-running-target">Run custom script after running target</h6>

<p>并不会覆盖默认的运行操作，只是在运行之后增加一些自定义的操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">after_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetset_config_h">target:set_config_h</h5>

<h6 id="set-auto-generated-config-header-file">Set auto-generated config header file</h6>

<p class="warning">
2.1.5版本之后，此接口已废弃，请使用[set_config_header](#targetset_config_header)。
</p>

<p>如果你想在xmake配置项目成功后，或者自动检测某个选项通过后，把检测的结果写入配置头文件，那么需要调用这个接口来启用自动生成<code class="highlighter-rouge">config.h</code>文件。</p>

<p>使用方式例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 启用并设置需要自动生成的config.h文件路径</span>
    <span class="n">set_config_h</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">)</span>

    <span class="c1">-- 设置自动检测生成的宏开关的名字前缀</span>
    <span class="n">set_config_h_prefix</span><span class="p">(</span><span class="s2">"TB_CONFIG"</span><span class="p">)</span>
</code></pre>
</div>

<p>当这个target中通过下面的这些接口，对这个target添加了相关的选项依赖、包依赖、接口依赖后，如果某依赖被启用，那么对应的一些宏定义配置，会自动写入被设置的<code class="highlighter-rouge">config.h</code>文件中去。</p>

<ul>
  <li><a href="#targetadd_options">add_options</a></li>
  <li><a href="#targetadd_packages">add_packages</a></li>
  <li><a href="#targetadd_cfuncs">add_cfuncs</a></li>
  <li><a href="#targetadd_cxxfuncs">add_cxxfuncs</a></li>
</ul>

<p>这些接口，其实底层都用到了<a href="#option">option</a>选项中的一些检测设置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>

    <span class="c1">-- 添加对wchar_t类型的检测</span>
    <span class="n">add_ctypes</span><span class="p">(</span><span class="s2">"wchar_t"</span><span class="p">)</span>

    <span class="c1">-- 如果检测通过，自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h</span>
    <span class="n">add_defines_h</span><span class="p">(</span><span class="s2">"$(prefix)_TYPE_HAVE_WCHAR"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 启用头文件自动生成</span>
    <span class="n">set_config_h</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">)</span>
    <span class="n">set_config_h_prefix</span><span class="p">(</span><span class="s2">"TB_CONFIG"</span><span class="p">)</span>

    <span class="c1">-- 添加对wchar选项的依赖关联，只有加上这个关联，wchar选项的检测结果才会写入指定的config.h中去</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetset_config_h_prefix">target:set_config_h_prefix</h5>

<h6 id="set-macro-prefix-in-auto-generated-config-header">Set macro prefix in auto-generated config header</h6>

<p class="warning">
2.1.5版本之后，此接口已废弃，请使用[set_config_header](#targetset_config_header)。
</p>

<p>具体使用见：<a href="#targetset_config_h">set_config_h</a></p>

<p>如果设置了：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_config_h_prefix</span><span class="p">(</span><span class="s2">"TB_CONFIG"</span><span class="p">)</span>
</code></pre>
</div>

<p>那么，选项中<code class="highlighter-rouge">add_defines_h("$(prefix)_TYPE_HAVE_WCHAR")</code>的$(prefix)会自动被替换成新的前缀值。</p>

<h5 id="targetset_config_header">target:set_config_header</h5>

<h6 id="set-auto-generated-config-header-file-new">Set auto-generated config header file (new)</h6>

<p>此接口是<a href="#targetset_config_h">set_config_h</a>和<a href="#targetset_config_h_prefix">set_config_h_prefix</a>的升级版本，2.1.5之后支持。</p>

<p>如果你想在xmake配置项目成功后，或者自动检测某个选项通过后，把检测的结果写入配置头文件，那么需要调用这个接口来启用自动生成<code class="highlighter-rouge">config.h</code>文件。</p>

<p>使用方式例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_config_header</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">,</span> <span class="p">{</span><span class="n">prefix</span> <span class="o">=</span> <span class="s2">"TB_CONFIG"</span><span class="p">})</span>
</code></pre>
</div>

<p>上面的代码，启用并设置需要自动生成的config.h文件路径，并且设置自动检测生成的宏开关的名字前缀：<code class="highlighter-rouge">TB_CONFIG</code>, 当然这个前缀的设置是可选的。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_config_header</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果不设置前缀，将会自动根据target名生成一个唯一字串。</p>

<p>当这个target中通过下面的这些接口，对这个target添加了相关的选项依赖、包依赖、接口依赖后，如果某依赖被启用，那么对应的一些宏定义配置，会自动写入被设置的<code class="highlighter-rouge">config.h</code>文件中去。</p>

<ul>
  <li><a href="#targetadd_options">add_options</a></li>
  <li><a href="#targetadd_packages">add_packages</a></li>
  <li><a href="#targetadd_cfuncs">add_cfuncs</a></li>
  <li><a href="#targetadd_cxxfuncs">add_cxxfuncs</a></li>
</ul>

<p>这些接口，其实底层都用到了<a href="#option">option</a>选项中的一些检测设置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>

    <span class="c1">-- 添加对wchar_t类型的检测</span>
    <span class="n">add_ctypes</span><span class="p">(</span><span class="s2">"wchar_t"</span><span class="p">)</span>

    <span class="c1">-- 如果检测通过，自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h</span>
    <span class="n">add_defines_h_if_ok</span><span class="p">(</span><span class="s2">"$(prefix)_TYPE_HAVE_WCHAR"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 启用头文件自动生成</span>
    <span class="n">set_config_header</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">,</span> <span class="p">{</span><span class="n">prefix</span> <span class="o">=</span> <span class="s2">"TB_CONFIG"</span><span class="p">})</span>

    <span class="c1">-- 添加对wchar选项的依赖关联，只有加上这个关联，wchar选项的检测结果才会写入指定的config.h中去</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>
</code></pre>
</div>

<p>2.1.8 之后版本，支持针对每个局部配置文件，单独设置版本号，优先于全局的<a href="#set_version">set_version</a>，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>    <span class="n">set_config_header</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">,</span> <span class="p">{</span><span class="n">prefix</span> <span class="o">=</span> <span class="s2">"TB_CONFIG"</span><span class="p">,</span> <span class="n">version</span> <span class="o">=</span> <span class="s2">"2.1.8"</span><span class="p">,</span> <span class="n">build</span> <span class="o">=</span> <span class="s2">"%Y%m%d%H%M"</span><span class="p">})</span>
</code></pre>
</div>

<h5 id="targetset_pcheader">target:set_pcheader</h5>

<h6 id="set-pre-compiled-c-header-file">Set pre-compiled c header file</h6>

<p>xmake支持通过预编译头文件去加速c程序编译，目前支持的编译器有：gcc, clang和msvc。</p>

<p>使用方式如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_pcheader</span><span class="p">(</span><span class="s2">"header.h"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetset_pcxxheader">target:set_pcxxheader</h5>

<h6 id="set-pre-compiled-c-header-file-1">Set pre-compiled c++ header file</h6>

<p>xmake支持通过预编译头文件去加速c++程序编译，目前支持的编译器有：gcc, clang和msvc。</p>

<p>使用方式如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_pcxxheader</span><span class="p">(</span><span class="s2">"header.h"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_deps">target:add_deps</h5>

<h6 id="add-target-dependencies">Add target dependencies</h6>

<p>添加当前目标的依赖目标，编译的时候，会去优先编译依赖的目标，然后再编译当前目标。。。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">set_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">set_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>

    <span class="c1">-- 添加依赖目标：test1, test2</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">,</span> <span class="s2">"test2"</span><span class="p">)</span>

    <span class="c1">-- 链接libtest1.a，libtest2.a</span>
    <span class="n">add_links</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">,</span> <span class="s2">"test2"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面的例子，在编译目标demo的时候，需要先编译test1, test2目标，因为demo会去用到他们</p>

<p class="tip">
2.1.5版本后，target会自动继承依赖目标中的配置和属性，不再需要额外调用`add_links`, `add_includedirs`和`add_linkdirs`等接口去关联依赖目标了。
</p>

<p>2.1.5版本之后，上述代码可简化为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">set_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">set_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">,</span> <span class="s2">"test2"</span><span class="p">)</span> <span class="c1">-- 会自动链接依赖目标</span>
</code></pre>
</div>

<p>并且继承关系是支持级联的，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"library1"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>
    <span class="n">add_headers</span><span class="p">(</span><span class="s2">"inc1/*.h"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"library2"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"library1"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"*.c"</span><span class="p">)</span>
    <span class="n">add_headers</span><span class="p">(</span><span class="s2">"inc2/*.h"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"library2"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果我们还是想以前那样，并不想继承依赖target的任何配置，如何操作呢？这个在2.1.6版本中也对其进行了支持，通过：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_deps</span><span class="p">(</span><span class="s2">"dep1"</span><span class="p">,</span> <span class="s2">"dep2"</span><span class="p">,</span> <span class="p">{</span><span class="n">inherit</span> <span class="o">=</span> <span class="kc">false</span><span class="p">})</span>
</code></pre>
</div>

<p>通过显示设置inherit配置，来告诉xmake，这两个依赖的配置是否需要被继承，如果不设置，默认就是启用继承的。</p>

<h5 id="targetadd_links">target:add_links</h5>

<h6 id="add-link-libraries">Add link libraries</h6>

<p>为当前目标添加链接库，一般这个要与<a href="#targetadd_linkdirs">add_linkdirs</a>配对使用。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>

    <span class="c1">-- 添加对libtest.a的链接，相当于 -ltest </span>
    <span class="n">add_links</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 添加链接搜索目录</span>
    <span class="n">add_linkdirs</span><span class="p">(</span><span class="s2">"$(buildir)/lib"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_files">target:add_files</h5>

<h6 id="add-source-files">Add source files</h6>

<p>用于添加目标工程的源文件，甚至库文件，目前支持的一些文件类型：</p>

<table>
  <thead>
    <tr>
      <th>支持的源文件类型</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>.c/.cpp/.cc/.cxx</td>
      <td>c++文件</td>
    </tr>
    <tr>
      <td>.s/.S/.asm</td>
      <td>汇编文件</td>
    </tr>
    <tr>
      <td>.m/.mm</td>
      <td>objc文件</td>
    </tr>
    <tr>
      <td>.swift</td>
      <td>swift文件</td>
    </tr>
    <tr>
      <td>.go</td>
      <td>golang文件</td>
    </tr>
    <tr>
      <td>.o/.obj</td>
      <td>对象文件</td>
    </tr>
    <tr>
      <td>.a/.lib</td>
      <td>静态库文件，会自动合并库到目标程序</td>
    </tr>
    <tr>
      <td>.rc</td>
      <td>msvc的资源文件</td>
    </tr>
  </tbody>
</table>

<p>其中通配符<code class="highlighter-rouge">*</code>表示匹配当前目录下文件，而<code class="highlighter-rouge">**</code>则匹配多级目录下的文件。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test_*.c"</span><span class="p">)</span>
<span class="n">add_files</span><span class="p">(</span><span class="s2">"src/xxx/**.cpp"</span><span class="p">)</span>
<span class="n">add_files</span><span class="p">(</span><span class="s2">"src/asm/*.S"</span><span class="p">,</span> <span class="s2">"src/objc/**/hello.m"</span><span class="p">)</span>
</code></pre>
</div>

<p><code class="highlighter-rouge">add_files</code>的使用其实是相当灵活方便的，其匹配模式借鉴了premake的风格，但是又对其进行了改善和增强。</p>

<p>使得不仅可以匹配文件，还有可以在添加文件同时，过滤排除指定模式的一批文件。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 递归添加src下的所有c文件，但是不包括src/impl/下的所有c文件</span>
<span class="n">add_files</span><span class="p">(</span><span class="s2">"src/**.c|impl/*.c"</span><span class="p">)</span>

<span class="c1">-- 添加src下的所有cpp文件，但是不包括src/test.cpp、src/hello.cpp以及src下所有带xx_前缀的cpp文件</span>
<span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.cpp|test.cpp|hello.cpp|xx_*.cpp"</span><span class="p">)</span>
</code></pre>
</div>

<p>其中分隔符<code class="highlighter-rouge">|</code>之后的都是需要排除的文件，这些文件也同样支持匹配模式，并且可以同时添加多个过滤模式，只要中间用<code class="highlighter-rouge">|</code>分割就行了。。</p>

<p>添加文件的时候支持过滤一些文件的一个好处就是，可以为后续根据不同开关逻辑添加文件提供基础。</p>

<p class="tip">
为了使得描述上更加的精简，`|`之后的过滤描述都是基于起一个模式：`src/*.cpp` 中`*`之前的目录为基础的。
所以上面的例子后面过滤的都是在src下的文件，这个是要注意的。
</p>

<p>2.1.6版本之后，对<code class="highlighter-rouge">add_files</code>进行了改进，支持基于files更细粒度的编译选项控制，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"TEST1"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"test/*.c"</span><span class="p">,</span> <span class="s2">"test2/test2.c"</span><span class="p">,</span> <span class="p">{</span><span class="n">defines</span> <span class="o">=</span> <span class="s2">"TEST2"</span><span class="p">,</span> <span class="n">languages</span> <span class="o">=</span> <span class="s2">"c99"</span><span class="p">,</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="s2">"."</span><span class="p">,</span> <span class="n">cflags</span> <span class="o">=</span> <span class="s2">"-O0"</span><span class="p">})</span>
</code></pre>
</div>

<p>可以在<code class="highlighter-rouge">add_files</code>的最后一个参数，传入一个配置table，去控制指定files的编译选项，里面的配置参数跟target的一致，并且这些文件还会继承target的通用配置<code class="highlighter-rouge">-DTEST1</code></p>

<p>2.1.9版本之后，支持添加未知的代码文件，通过设置rule自定义规则，实现这些文件的自定义构建，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- ...</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test/*.md"</span><span class="p">,</span> <span class="p">{</span><span class="n">rule</span> <span class="o">=</span> <span class="s2">"markdown"</span><span class="p">})</span>
</code></pre>
</div>

<p>关于自定义构建规则的使用说明，详细见：<a href="#构建规则">构建规则</a>。</p>

<p>并且在2.1.9版本之后，可以通过force参数来强制禁用cxflags,cflags等编译选项的自动检测，直接传入编译器，哪怕编译器有可能不支持，也会设置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">,</span> <span class="p">{</span><span class="n">force</span> <span class="o">=</span> <span class="p">{</span><span class="n">cxflags</span> <span class="o">=</span> <span class="s2">"-DTEST"</span><span class="p">,</span> <span class="n">mflags</span> <span class="o">=</span> <span class="s2">"-framework xxx"</span><span class="p">}})</span>
</code></pre>
</div>

<h5 id="targetdel_files">target:del_files</h5>

<h6 id="remove-source-files">Remove source files</h6>

<p>通过此接口，可以从前面<a href="targetadd_files">add_files</a>接口添加的文件列表中，删除指定的文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">del_files</span><span class="p">(</span><span class="s2">"src/test.c"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面的例子，可以从<code class="highlighter-rouge">src</code>目录下添加除<code class="highlighter-rouge">test.c</code>以外的所有文件，当然这个也可以通过<code class="highlighter-rouge">add_files("src/*.c|test.c")</code>来达到相同的目的，但是这种方式更加灵活。</p>

<p>例如，我们可以条件判断来控制删除哪些文件，并且此接口也支持<a href="targetadd_files">add_files</a>的匹配模式，过滤模式，进行批量移除。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/**.c"</span><span class="p">)</span>
    <span class="n">del_files</span><span class="p">(</span><span class="s2">"src/test*.c"</span><span class="p">)</span>
    <span class="n">del_files</span><span class="p">(</span><span class="s2">"src/subdir/*.c|xxx.c"</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span> <span class="k">then</span>
        <span class="n">add_files</span><span class="p">(</span><span class="s2">"xxx.m"</span><span class="p">)</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>通过上面的例子，我们可以看出<code class="highlighter-rouge">add_files</code>和<code class="highlighter-rouge">del_files</code>是根据调用顺序，进行顺序添加和删除的，并且通过<code class="highlighter-rouge">del_files("src/subdir/*.c|xxx.c")</code>删除一批文件，
并且排除<code class="highlighter-rouge">src/subdir/xxx.c</code>（就是说，不删除这个文件）。</p>

<h5 id="targetadd_headers">target:add_headers</h5>

<h6 id="add-installed-header-files">Add installed header files</h6>

<p>安装指定的头文件到build目录，如果设置了<a href="#targetset_headerdir">set_headerdir</a>， 则输出到指定目录。</p>

<p>安装规则的语法跟<a href="#targetadd_files">add_files</a>类似，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>    <span class="c1">-- 安装tbox目录下所有的头文件（忽略impl目录下的文件），并且按()指定部分作为相对路径，进行安装</span>
    <span class="n">add_headers</span><span class="p">(</span><span class="s2">"../(tbox/**.h)|**/impl/**.h"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_linkdirs">target:add_linkdirs</h5>

<h6 id="add-link-search-directories">Add link search directories</h6>

<p>设置链接库的搜索目录，这个接口的使用方式如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_linkdirs</span><span class="p">(</span><span class="s2">"$(buildir)/lib"</span><span class="p">)</span>
</code></pre>
</div>

<p>此接口相当于gcc的<code class="highlighter-rouge">-Lxxx</code>链接选项。</p>

<p>一般他是与<a href="#targetadd_links">add_links</a>配合使用的，当然也可以直接通过<a href="#targetadd_ldflags">add_ldflags</a>或者<a href="#targetadd_shflags">add_shflags</a>接口来添加，也是可以的。</p>

<p class="tip">
如果不想在工程中写死，可以通过：`xmake f --linkdirs=xxx`或者`xmake f --ldflags="-L/xxx"`的方式来设置，当然这种手动设置的目录搜索优先级更高。
</p>

<h5 id="targetadd_rpathdirs">target:add_rpathdirs</h5>

<h6 id="add-load-search-directories-for-dynamic-libraries">Add load search directories for dynamic libraries</h6>

<p>通过<a href="#targetadd_linkdirs">add_linkdirs</a>设置动态库的链接搜索目录后，程序被正常链接，但是在linux平台想要正常运行编译后的程序，会报加载动态库失败。</p>

<p>因为没找到动态库的加载目录，想要正常运行依赖动态库的程序，需要设置<code class="highlighter-rouge">LD_LIBRARY_PATH</code>环境变量，指定需要加载的动态库目录。</p>

<p>但是这种方式是全局的，影响太广，更好的方式是通过<code class="highlighter-rouge">-rpath=xxx</code>的链接器选项，在链接程序的时候设置好需要加载的动态库搜索路径，而xmake对其进行了封装，通过<code class="highlighter-rouge">add_rpathdirs</code>更好的处理跨平台问题。</p>

<p>具体使用如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_linkdirs</span><span class="p">(</span><span class="s2">"$(buildir)/lib"</span><span class="p">)</span>
    <span class="n">add_rpathdirs</span><span class="p">(</span><span class="s2">"$(buildir)/lib"</span><span class="p">)</span>
</code></pre>
</div>

<p>只需要在链接的时候，在设置下rpath目录就好了，虽然也可以通过<code class="highlighter-rouge">add_ldflags("-Wl,-rpath=xxx")</code>达到相同的目的，但是这个接口更加通用。</p>

<p>内部会对不同平台进行处理，像在macOS下，是不需要<code class="highlighter-rouge">-rpath</code>设置的，也是可以正常加载运行程序，因此针对这个平台，xmake内部会直接忽略器设置，避免链接报错。</p>

<p>而在为dlang程序进行动态库链接时，xmake会自动处理成<code class="highlighter-rouge">-L-rpath=xxx</code>来传入dlang的链接器，这样就避免了直接使用<code class="highlighter-rouge">add_ldflags</code>需要自己判断和处理不同平台和编译器问题。</p>

<p>2.1.7版本对这个接口进行了改进，支持：<code class="highlighter-rouge">@loader_path</code>, <code class="highlighter-rouge">@executable_path</code> 和 <code class="highlighter-rouge">$ORIGIN</code>的内置变量，来指定程序的加载目录，它们的效果基本上是一样的，主要是为了同时兼容macho, elf。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_linkdirs</span><span class="p">(</span><span class="s2">"$(buildir)/lib"</span><span class="p">)</span>
    <span class="n">add_rpathdirs</span><span class="p">(</span><span class="s2">"@loader_path/lib"</span><span class="p">)</span>
</code></pre>
</div>

<p>指定test程序加载当前执行目录下<code class="highlighter-rouge">lib/*.[so|dylib]</code>的动态库文件，这将有助于提升程序的可移植性，不用写死绝对路径和相对路径，导致程序和目录切换引起程序加载动态库失败。</p>

<h5 id="targetadd_includedirs">target:add_includedirs</h5>

<h6 id="add-include-search-directories">Add include search directories</h6>

<p>设置头文件的搜索目录，这个接口的使用方式如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_includedirs</span><span class="p">(</span><span class="s2">"$(buildir)/include"</span><span class="p">)</span>
</code></pre>
</div>

<p>当然也可以直接通过<a href="#targetadd_cxflags">add_cxflags</a>或者<a href="#targetadd_mxflags">add_mxflags</a>等接口来设置，也是可以的。</p>

<p class="tip">
如果不想在工程中写死，可以通过：`xmake f --includedirs=xxx`或者`xmake f --cxflags="-I/xxx"`的方式来设置，当然这种手动设置的目录搜索优先级更高。
</p>

<h5 id="targetadd_defines">target:add_defines</h5>

<h6 id="add-macro-definition">Add macro definition</h6>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">,</span> <span class="s2">"TEST=0"</span><span class="p">,</span> <span class="s2">"TEST2=\"</span><span class="n">hello</span><span class="err">\</span><span class="s2">""</span><span class="p">)</span>
</code></pre>
</div>

<p>相当于设置了编译选项：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>-DDEBUG -DTEST=0 -DTEST2=\"hello\"
</code></pre>
</div>

<h5 id="targetadd_undefines">target:add_undefines</h5>

<h6 id="add-macro-undefinition">Add macro undefinition</h6>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_undefines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>
</code></pre>
</div>

<p>相当于设置了编译选项：<code class="highlighter-rouge">-UDEBUG</code></p>

<p>在代码中相当于：<code class="highlighter-rouge">#undef DEBUG</code></p>

<h5 id="targetadd_defines_h">target:add_defines_h</h5>

<h6 id="add-macro-definition-to-auto-generated-config-header">Add macro definition to auto-generated config header</h6>

<p>添加宏定义到<code class="highlighter-rouge">config.h</code>配置文件，<code class="highlighter-rouge">config.h</code>的设置，可参考<a href="#targetset_config_h">set_config_h</a>接口。</p>

<h5 id="targetadd_undefines_h">target:add_undefines_h</h5>

<h6 id="add-macro-undefinition-to-auto-generated-config-header">Add macro undefinition to auto-generated config header</h6>

<p>在<code class="highlighter-rouge">config.h</code>配置文件中通过<code class="highlighter-rouge">undef</code>禁用宏定义，<code class="highlighter-rouge">config.h</code>的设置，可参考<a href="#targetset_config_h">set_config_h</a>接口。</p>

<h5 id="targetadd_cflags">target:add_cflags</h5>

<h6 id="add-c-compilation-flags">Add c compilation flags</h6>

<p>仅对c代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_cflags</span><span class="p">(</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O2"</span><span class="p">,</span> <span class="s2">"-DDEBUG"</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
所有选项值都基于gcc的定义为标准，如果其他编译器不兼容（例如：vc），xmake会自动内部将其转换成对应编译器支持的选项值。
用户无需操心其兼容性，如果其他编译器没有对应的匹配值，那么xmake会自动忽略器设置。
</p>

<p>在2.1.9版本之后，可以通过force参数来强制禁用flags的自动检测，直接传入编译器，哪怕编译器有可能不支持，也会设置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_cflags</span><span class="p">(</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O2"</span><span class="p">,</span> <span class="p">{</span><span class="n">force</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<h5 id="targetadd_cxflags">target:add_cxflags</h5>

<h6 id="add-cc-compilation-flags">Add c/c++ compilation flags</h6>

<p>同时对c/c++代码添加编译选项</p>

<h5 id="targetadd_cxxflags">target:add_cxxflags</h5>

<h6 id="add-c-compilation-flags-1">Add c++ compilation flags</h6>

<p>仅对c++代码添加编译选项</p>

<h5 id="targetadd_mflags">target:add_mflags</h5>

<h6 id="add-objc-compilation-flags">Add objc compilation flags</h6>

<p>仅对objc代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_mflags</span><span class="p">(</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O2"</span><span class="p">,</span> <span class="s2">"-DDEBUG"</span><span class="p">)</span>
</code></pre>
</div>

<p>在2.1.9版本之后，可以通过force参数来强制禁用flags的自动检测，直接传入编译器，哪怕编译器有可能不支持，也会设置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_mflags</span><span class="p">(</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O2"</span><span class="p">,</span> <span class="p">{</span><span class="n">force</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<h5 id="targetadd_mxflags">target:add_mxflags</h5>

<h6 id="add-objcobjc-compilation-flags">Add objc/objc++ compilation flags</h6>

<p>同时对objc/objc++代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_mxflags</span><span class="p">(</span><span class="s2">"-framework CoreFoundation"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_mxxflags">target:add_mxxflags</h5>

<h6 id="add-objc-compilation-flags-1">Add objc++ compilation flags</h6>

<p>仅对objc++代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_mxxflags</span><span class="p">(</span><span class="s2">"-framework CoreFoundation"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_scflags">target:add_scflags</h5>

<h6 id="add-swift-compilation-flags">Add swift compilation flags</h6>

<p>对swift代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_scflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_asflags">target:add_asflags</h5>

<h6 id="add-asm-compilation-flags">Add asm compilation flags</h6>

<p>对汇编代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_asflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_gcflags">target:add_gcflags</h5>

<h6 id="add-go-compilation-flags">Add go compilation flags</h6>

<p>对golang代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_gcflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_dcflags">target:add_dcflags</h5>

<h6 id="add-dlang-compilation-flags">Add dlang compilation flags</h6>

<p>对dlang代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_dcflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_rcflags">target:add_rcflags</h5>

<h6 id="add-rust-compilation-flags">Add rust compilation flags</h6>

<p>对rust代码添加编译选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_rcflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_ldflags">target:add_ldflags</h5>

<h6 id="add-static-library-link-flags">Add static library link flags</h6>

<p>添加静态链接选项</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_ldflags</span><span class="p">(</span><span class="s2">"-L/xxx"</span><span class="p">,</span> <span class="s2">"-lxxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_arflags">target:add_arflags</h5>

<h6 id="add-archive-library-flags">Add archive library flags</h6>

<p>影响对静态库的生成</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_arflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>
<h5 id="targetadd_shflags">target:add_shflags</h5>

<h6 id="add-dynamic-library-link-flags">Add dynamic library link flags</h6>

<p>影响对动态库的生成</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_shflags</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="targetadd_cfunc">target:add_cfunc</h5>

<h6 id="add-single-c-function-for-checking">Add single c function for checking</h6>

<p>与<a href="#targetadd_cfuncs">add_cfuncs</a>类似，只是仅对单个函数接口进行设置，并且仅对<code class="highlighter-rouge">target</code>域生效，<code class="highlighter-rouge">option</code>中不存在此接口。</p>

<p>此接口的目的主要是为了在<code class="highlighter-rouge">config.h</code>中更加高度定制化的生成宏开关，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    
    <span class="c1">-- 设置和启用config.h</span>
    <span class="n">set_config_h</span><span class="p">(</span><span class="s2">"$(buildir)/config.h"</span><span class="p">)</span>
    <span class="n">set_config_h_prefix</span><span class="p">(</span><span class="s2">"TEST"</span><span class="p">)</span>

    <span class="c1">-- 仅通过参数一设置模块名前缀</span>
    <span class="n">add_cfunc</span><span class="p">(</span><span class="s2">"libc"</span><span class="p">,</span>       <span class="kc">nil</span><span class="p">,</span>        <span class="kc">nil</span><span class="p">,</span>        <span class="p">{</span><span class="s2">"sys/select.h"</span><span class="p">},</span>   <span class="s2">"select"</span><span class="p">)</span>

    <span class="c1">-- 通过参数三，设置同时检测链接库：libpthread.a</span>
    <span class="n">add_cfunc</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">,</span>    <span class="kc">nil</span><span class="p">,</span>        <span class="s2">"pthread"</span><span class="p">,</span>  <span class="s2">"pthread.h"</span><span class="p">,</span>        <span class="s2">"pthread_create"</span><span class="p">)</span>

    <span class="c1">-- 通过参数二设置接口别名</span>
    <span class="n">add_cfunc</span><span class="p">(</span><span class="kc">nil</span><span class="p">,</span>          <span class="s2">"PTHREAD"</span><span class="p">,</span>  <span class="kc">nil</span><span class="p">,</span>        <span class="s2">"pthread.h"</span><span class="p">,</span>        <span class="s2">"pthread_create"</span><span class="p">)</span>
</code></pre>
</div>

<p>生成的结果如下：</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="cp">#ifndef TEST_H
#define TEST_H
</span>
<span class="c1">// 宏命名规则：$(prefix)前缀 _ 模块名（如果非nil）_ HAVE _ 接口名或者别名 （大写）
</span><span class="cp">#define TEST_LIBC_HAVE_SELECT 1
#define TEST_PTHREAD_HAVE_PTHREAD_CREATE 1
#define TEST_HAVE_PTHREAD 1
</span>
<span class="cp">#endif
</span></code></pre>
</div>

<p>如果要更加灵活的函数检测，可以通过<a href="#detect-has_cfuncs">lib.detect.has_cfuncs</a>在自定义脚本中实现。</p>

<h5 id="targetadd_cxxfunc">target:add_cxxfunc</h5>

<h6 id="add-single-c-function-for-checking-1">Add single c++ function for checking</h6>

<p>与<a href="#targetadd_cfunc">add_cfunc</a>类似，只是检测的函数接口是c++函数。</p>

<h5 id="targetadd_cfuncs">target:add_cfuncs</h5>

<h6 id="add-c-functions-for-checking">Add c functions for checking</h6>

<p class="warning">
此接口是`target`和`option`共用的接口，但是接口行为稍有不同。
</p>

<table>
  <thead>
    <tr>
      <th>接口域</th>
      <th>描述</th>
      <th>例子</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>target</td>
      <td>头文件、链接库和函数接口同时指定</td>
      <td><code class="highlighter-rouge">add_cfuncs("libc", nil, {"signal.h", "setjmp.h"}, "signal", "setjmp", "sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}", "kill")</code></td>
    </tr>
    <tr>
      <td>option</td>
      <td>仅指定函数接口，头文件依赖<a href="#targetadd_cincludes">add_cincludes</a>等独立接口</td>
      <td><code class="highlighter-rouge">add_cincludes("setjmp.h")</code> <code class="highlighter-rouge">add_cfuncs("sigsetjmp")</code></td>
    </tr>
  </tbody>
</table>

<p>对于<code class="highlighter-rouge">option</code>，这个接口的使用很简单，跟<a href="#targetadd_cincludes">add_cincludes</a>类似，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"setjmp"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">add_cincludes</span><span class="p">(</span><span class="s2">"setjmp.h"</span><span class="p">)</span>
    <span class="n">add_cfuncs</span><span class="p">(</span><span class="s2">"sigsetjmp"</span><span class="p">,</span> <span class="s2">"setjmp"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"HAVE_SETJMP"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"setjmp"</span><span class="p">)</span>
</code></pre>
</div>

<p>此选项检测是否存在<code class="highlighter-rouge">setjmp</code>的一些接口，如果检测通过那么<code class="highlighter-rouge">test</code>目标程序将会加上<code class="highlighter-rouge">HAVE_SETJMP</code>的宏定义。</p>

<p class="warning">
需要注意的是，在`option`中使用此接口检测依赖函数，需要同时使用独立的[add_cincludes](#targetadd_cincludes)增加头文件搜索路径，指定[add_links](#targetadd_links)链接库（可选），否则检测不到指定函数。
<br /><br />
并且某些头文件接口是通过宏开关分别定义的，那么检测的时候最好通过[add_defines](#targetadd_defines)带上依赖的宏开关。
</p>

<p>对于<code class="highlighter-rouge">target</code>，此接口可以同时设置：依赖的头文件、依赖的链接模块、依赖的函数接口，保证检测环境的完整性，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 添加libc库接口相关检测</span>
    <span class="c1">-- 第一个参数：模块名，用于最后的宏定义前缀生成</span>
    <span class="c1">-- 第二个参数：链接库</span>
    <span class="c1">-- 第三个参数：头文件</span>
    <span class="c1">-- 之后的都是函数接口列表</span>
    <span class="n">add_cfuncs</span><span class="p">(</span><span class="s2">"libc"</span><span class="p">,</span> <span class="kc">nil</span><span class="p">,</span>         <span class="p">{</span><span class="s2">"signal.h"</span><span class="p">,</span> <span class="s2">"setjmp.h"</span><span class="p">},</span>           <span class="s2">"signal"</span><span class="p">,</span> <span class="s2">"setjmp"</span><span class="p">,</span> <span class="s2">"sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}"</span><span class="p">,</span> <span class="s2">"kill"</span><span class="p">)</span>

    <span class="c1">-- 添加pthread库接口相关检测，同时指定需要检测`libpthread.a`链接库是否存在</span>
    <span class="n">add_cfuncs</span><span class="p">(</span><span class="s2">"posix"</span><span class="p">,</span> <span class="s2">"pthread"</span><span class="p">,</span>  <span class="s2">"pthread.h"</span><span class="p">,</span>                        <span class="s2">"pthread_mutex_init"</span><span class="p">,</span>
                                                                        <span class="s2">"pthread_create"</span><span class="p">,</span> 
                                                                        <span class="s2">"pthread_setspecific"</span><span class="p">,</span> 
                                                                        <span class="s2">"pthread_getspecific"</span><span class="p">,</span>
                                                                        <span class="s2">"pthread_key_create"</span><span class="p">,</span>
                                                                        <span class="s2">"pthread_key_delete"</span><span class="p">)</span>
</code></pre>
</div>

<p>设置<code class="highlighter-rouge">test</code>目标，依赖这些接口，构建时会预先检测他们，并且如果通过<a href="#targetset_config_h">set_config_h</a>接口设置的自动生成头文件：<code class="highlighter-rouge">config.h</code></p>

<p>那么，检测结果会自动加到对应的<code class="highlighter-rouge">config.h</code>上去，这也是<code class="highlighter-rouge">option</code>没有的功能，例如：</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="cp">#define TB_CONFIG_LIBC_HAVE_SIGNAL 1
#define TB_CONFIG_LIBC_HAVE_SETJMP 1
#define TB_CONFIG_LIBC_HAVE_SIGSETJMP 1
#define TB_CONFIG_LIBC_HAVE_KILL 1
</span>
<span class="cp">#define TB_CONFIG_POSIX_HAVE_PTHREAD_MUTEX_INIT 1
#define TB_CONFIG_POSIX_HAVE_PTHREAD_CREATE 1
#define TB_CONFIG_POSIX_HAVE_PTHREAD_SETSPECIFIC 1
#define TB_CONFIG_POSIX_HAVE_PTHREAD_GETSPECIFIC 1
#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_CREATE 1
#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_DELETE 1
</span></code></pre>
</div>

<p>由于，不同头文件中，函数的定义方式不完全相同，例如：宏函数、静态内联函数、extern函数等。</p>

<p>要想完全检测成功，检测语法上需要一定程度的灵活性，下面是一些语法规则：</p>

<table>
  <thead>
    <tr>
      <th>检测语法</th>
      <th>例子</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>纯函数名</td>
      <td><code class="highlighter-rouge">sigsetjmp</code></td>
    </tr>
    <tr>
      <td>单行调用</td>
      <td><code class="highlighter-rouge">sigsetjmp((void*)0, 0)</code></td>
    </tr>
    <tr>
      <td>函数块调用</td>
      <td><code class="highlighter-rouge">sigsetjmp{sigsetjmp((void*)0, 0);}</code></td>
    </tr>
    <tr>
      <td>函数块 + 变量</td>
      <td><code class="highlighter-rouge">sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}</code></td>
    </tr>
  </tbody>
</table>

<h5 id="targetadd_cxxfuncs">target:add_cxxfuncs</h5>

<h6 id="add-c-functions-for-checking-1">Add c++ functions for checking</h6>

<p>与<a href="#targetadd_cfuncs">add_cfuncs</a>类似，只是检测的函数接口是c++函数。</p>

<h5 id="targetadd_options">target:add_options</h5>

<h6 id="add-option-dependencies">Add option dependencies</h6>

<p>这个接口跟<a href="#targetset_options">set_options</a>类似，唯一的区别就是，此处是追加选项，而<a href="#targetset_options">set_options</a>每次设置会覆盖先前的设置。</p>

<h5 id="targetadd_packages">target:add_packages</h5>

<h6 id="add-package-dependencies">Add package dependencies</h6>

<p>在target作用域中，添加集成包依赖，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_packages</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"polarssl"</span><span class="p">,</span> <span class="s2">"pcre"</span><span class="p">,</span> <span class="s2">"mysql"</span><span class="p">)</span>
</code></pre>
</div>

<p>这样，在编译test目标时，如果这个包存在的，将会自动追加包里面的宏定义、头文件搜索路径、链接库目录，也会自动链接包中所有库。</p>

<p>用户不再需要自己单独调用<a href="#targetadd_links">add_links</a>，<a href="#targetadd_includedirs">add_includedirs</a>, <a href="#targetadd_ldflags">add_ldflags</a>等接口，来配置依赖库链接了。</p>

<p>对于如何设置包搜索目录，可参考：<a href="#targetadd_packagedirs">add_packagedirs</a> 接口</p>

<h5 id="targetadd_languages">target:add_languages</h5>

<h6 id="add-language-standards">Add language standards</h6>

<p>与<a href="#targetset_languages">set_languages</a>类似，唯一区别是这个接口不会覆盖掉之前的设置，而是追加设置。</p>

<h5 id="targetadd_vectorexts">target:add_vectorexts</h5>

<h6 id="add-vector-extensions">Add vector extensions</h6>

<p>添加扩展指令优化选项，目前支持以下几种扩展指令集：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_vectorexts</span><span class="p">(</span><span class="s2">"mmx"</span><span class="p">)</span>
<span class="n">add_vectorexts</span><span class="p">(</span><span class="s2">"neon"</span><span class="p">)</span>
<span class="n">add_vectorexts</span><span class="p">(</span><span class="s2">"avx"</span><span class="p">,</span> <span class="s2">"avx2"</span><span class="p">)</span>
<span class="n">add_vectorexts</span><span class="p">(</span><span class="s2">"sse"</span><span class="p">,</span> <span class="s2">"sse2"</span><span class="p">,</span> <span class="s2">"sse3"</span><span class="p">,</span> <span class="s2">"ssse3"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
如果当前设置的指令集编译器不支持，xmake会自动忽略掉，所以不需要用户手动去判断维护，只需要将你需要的指令集全部设置上就行了。
</p>

<h5 id="targetadd_frameworks">target:add_frameworks</h5>

<h6 id="add-frameworks">Add frameworks</h6>

<p>目前主要用于<code class="highlighter-rouge">ios</code>和<code class="highlighter-rouge">macosx</code>平台的<code class="highlighter-rouge">objc</code>和<code class="highlighter-rouge">swift</code>程序，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_frameworks</span><span class="p">(</span><span class="s2">"Foundation"</span><span class="p">,</span> <span class="s2">"CoreFoundation"</span><span class="p">)</span>
</code></pre>
</div>

<p>当然也可以使用<a href="#targetadd_mxflags">add_mxflags</a>和<a href="#targetadd_ldflags">add_ldflags</a>来设置，不过比较繁琐，不建议这样设置。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_mxflags</span><span class="p">(</span><span class="s2">"-framework Foundation"</span><span class="p">,</span> <span class="s2">"-framework CoreFoundation"</span><span class="p">)</span>
    <span class="n">add_ldflags</span><span class="p">(</span><span class="s2">"-framework Foundation"</span><span class="p">,</span> <span class="s2">"-framework CoreFoundation"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果不是这两个平台，这些设置将会被忽略。</p>

<h5 id="targetadd_frameworkdirs">target:add_frameworkdirs</h5>

<h6 id="add-framework-search-directories">Add framework search directories</h6>

<p>对于一些第三方framework，那么仅仅通过<a href="#targetadd_frameworks">add_frameworks</a>是没法找到的，还需要通过这个接口来添加搜索目录。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_frameworks</span><span class="p">(</span><span class="s2">"MyFramework"</span><span class="p">)</span>
    <span class="n">add_frameworkdirs</span><span class="p">(</span><span class="s2">"/tmp/frameworkdir"</span><span class="p">,</span> <span class="s2">"/tmp/frameworkdir2"</span><span class="p">)</span>
</code></pre>
</div>

<h4 id="configuration-option">Configuration Option</h4>

<p>定义和设置选项开关，每个<code class="highlighter-rouge">option</code>对应一个选项，可用于自定义编译配置选项、开关设置。</p>

<p class="tip">
除了`target`以外的所有域接口，例如`option`，`task`等的接口，默认不能放置在外面的全局作用域中的（除非部分跟target共用的接口除外）。
如果要设置值影响所有`option`，`task`等选项，可以通过匿名全局域来设置。
</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 进入option的匿名全局域，里面的设置会同时影响test和test2选项</span>
<span class="n">option</span><span class="p">()</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- ... </span>
    <span class="c1">-- 尽量保持缩进，因为这个之后的所有设置，都是针对test选项的</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="c1">-- ... </span>
</code></pre>
</div>

<p class="tip">
`option`域是可以重复进入来实现分离设置的，如果要显示离开当前选项的作用域设置，可以手动调用[option_end](#option_end)接口。
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#option">option</a></td>
      <td>定义选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#option_end">option_end</a></td>
      <td>结束定义选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_deps">add_deps</a></td>
      <td>添加选项依赖</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionbefore_check">before_check</a></td>
      <td>选项检测之前执行此脚本</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionon_check">on_check</a></td>
      <td>自定义选项检测脚本</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionafter_check">after_check</a></td>
      <td>选项检测之后执行此脚本</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionset_values">set_values</a></td>
      <td>设置选项值列表</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#optionset_default">set_default</a></td>
      <td>设置默认值</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionset_showmenu">set_showmenu</a></td>
      <td>设置是否启用菜单显示</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionset_category">set_category</a></td>
      <td>设置选项分类，仅用于菜单显示</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionset_description">set_description</a></td>
      <td>设置菜单显示描述</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_links">add_links</a></td>
      <td>添加链接库检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_linkdirs">add_linkdirs</a></td>
      <td>添加链接库检测需要的搜索目录</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_rpathdirs">add_rpathdirs</a></td>
      <td>添加运行时候动态链接库搜索目录</td>
      <td>&gt;= 2.1.3</td>
    </tr>
    <tr>
      <td><a href="#optionadd_cincludes">add_cincludes</a></td>
      <td>添加c头文件检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_cxxincludes">add_cxxincludes</a></td>
      <td>添加c++头文件检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_ctypes">add_ctypes</a></td>
      <td>添加c类型检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_cxxtypes">add_cxxtypes</a></td>
      <td>添加c++类型检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#optionadd_csnippet">add_csnippet</a></td>
      <td>添加c代码片段检测</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_cxxsnippet">add_cxxsnippet</a></td>
      <td>添加c++代码片段检测</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#targetset_warnings">set_warnings</a></td>
      <td>设置警告级别</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_optimize">set_optimize</a></td>
      <td>设置优化级别</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetset_languages">set_languages</a></td>
      <td>设置代码语言标准</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_includedirs">add_includedirs</a></td>
      <td>添加头文件搜索目录</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_defines">add_defines</a></td>
      <td>添加宏定义</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_undefines">add_undefines</a></td>
      <td>取消宏定义</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_defines_h">add_defines_h</a></td>
      <td>添加宏定义到头文件</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_undefines_h">add_undefines_h</a></td>
      <td>取消宏定义到头文件</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cflags">add_cflags</a></td>
      <td>添加c编译选项</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxflags">add_cxflags</a></td>
      <td>添加c/c++编译选项</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxxflags">add_cxxflags</a></td>
      <td>添加c++编译选项</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mflags">add_mflags</a></td>
      <td>添加objc编译选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mxflags">add_mxflags</a></td>
      <td>添加objc/objc++编译选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_mxxflags">add_mxxflags</a></td>
      <td>添加objc++编译选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_scflags">add_scflags</a></td>
      <td>添加swift编译选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_asflags">add_asflags</a></td>
      <td>添加汇编编译选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_gcflags">add_gcflags</a></td>
      <td>添加go编译选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_dcflags">add_dcflags</a></td>
      <td>添加dlang编译选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_rcflags">add_rcflags</a></td>
      <td>添加rust编译选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_ldflags">add_ldflags</a></td>
      <td>添加链接选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_arflags">add_arflags</a></td>
      <td>添加静态库归档选项</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_shflags">add_shflags</a></td>
      <td>添加动态库链接选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cfuncs">add_cfuncs</a></td>
      <td>添加c库函数检测</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_cxxfuncs">add_cxxfuncs</a></td>
      <td>添加c++库函数接口</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_languages">add_languages</a></td>
      <td>添加语言标准</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_vectorexts">add_vectorexts</a></td>
      <td>添加向量扩展指令</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_frameworks">add_frameworks</a></td>
      <td>添加链接框架</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#targetadd_frameworkdirs">add_frameworkdirs</a></td>
      <td>添加链接框架</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<table>
  <thead>
    <tr>
      <th>废弃接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#optionadd_bindings">add_bindings</a></td>
      <td>添加正向关联选项，同步启用和禁用</td>
      <td>&gt;= 2.0.1 &lt; 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_rbindings">add_rbindings</a></td>
      <td>添加逆向关联选项，同步启用和禁用</td>
      <td>&gt;= 2.0.1 &lt; 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_defines_if_ok">add_defines_if_ok</a></td>
      <td>如果检测选项通过，则添加宏定义</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_defines_h_if_ok">add_defines_h_if_ok</a></td>
      <td>如果检测选项通过，则添加宏定义到配置头文件</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_undefines_if_ok">add_undefines_if_ok</a></td>
      <td>如果检测选项通过，则取消宏定义</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#optionadd_undefines_h_if_ok">add_undefines_h_if_ok</a></td>
      <td>如果检测选项通过，则在配置头文件中取消宏定义</td>
      <td>&gt;= 1.0.1 &lt; 2.1.5</td>
    </tr>
  </tbody>
</table>

<h5 id="option">option</h5>

<h6 id="定义选项">定义选项</h6>

<p>定义和设置选项开关，可用于自定义编译配置选项、开关设置。</p>

<p>例如，定义一个是否启用test的选项：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"TEST"</span><span class="p">)</span>
</code></pre>
</div>

<p>然后关联到指定的target中去：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
</code></pre>
</div>

<p>这样，一个选项就算定义好了，如果这个选项被启用，那么编译这个target的时候，就会自动加上<code class="highlighter-rouge">-DTEST</code>的宏定义。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="o">#</span> <span class="err">手动启用这个选项</span>
<span class="err">$</span> <span class="n">xmake</span> <span class="n">f</span> <span class="c1">--test=y</span>
<span class="err">$</span> <span class="n">xmake</span>
</code></pre>
</div>

<h5 id="option_end">option_end</h5>

<h6 id="结束定义选项">结束定义选项</h6>

<p>这是一个可选api，显示离开选项作用域，用法和<a href="#target_end">target_end</a>类似。</p>

<h5 id="optionadd_deps">option:add_deps</h5>

<h6 id="添加选项依赖">添加选项依赖</h6>

<p>通过设置依赖，可以调整选项的检测顺序，一般用于<a href="#optionon_check">on_check</a>等检测脚本的调用时机。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"small"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">on_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="c1">-- ...</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"small"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">on_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">option</span><span class="p">:</span><span class="n">dep</span><span class="p">(</span><span class="s2">"small"</span><span class="p">):</span><span class="n">enabled</span><span class="p">()</span> <span class="k">then</span>
            <span class="n">option</span><span class="p">:</span><span class="n">enable</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>当依赖的small选项检测完成后，通过判断small选项的状态，来控制test的选项状态。</p>

<h5 id="optionbefore_check">option:before_check</h5>

<h6 id="选项检测之前执行此脚本">选项检测之前执行此脚本</h6>

<p>例如：在检测之前，通过<a href="#detect-find_package">find_package</a>来查找包，将<code class="highlighter-rouge">links</code>, <code class="highlighter-rouge">includedirs</code>和<code class="highlighter-rouge">linkdirs</code>等信息添加到option中去，
然后开始选项检测，通过后就会自动链接到target上。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">)</span>
    <span class="n">before_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_package"</span><span class="p">)</span>
        <span class="n">option</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="n">find_package</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="optionon_check">option:on_check</h5>

<h6 id="自定义选项检测脚本">自定义选项检测脚本</h6>

<p>此脚本会覆盖内置的选项检测逻辑。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"small"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">on_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">option</span><span class="p">:</span><span class="n">dep</span><span class="p">(</span><span class="s2">"small"</span><span class="p">):</span><span class="n">enabled</span><span class="p">()</span> <span class="k">then</span>
            <span class="n">option</span><span class="p">:</span><span class="n">enable</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>如果test依赖的选项通过，则禁用test选项。</p>

<h5 id="optionafter_check">option:after_check</h5>

<h6 id="选项检测之后执行此脚本">选项检测之后执行此脚本</h6>

<p>在选项检测完成后，执行此脚本做一些后期处理，也可以在此时重新禁用选项：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_deps</span><span class="p">(</span><span class="s2">"small"</span><span class="p">)</span>
    <span class="n">add_links</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
    <span class="n">after_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="n">option</span><span class="p">:</span><span class="n">enable</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="optionset_values">option:set_values</h5>

<h6 id="设置选项值列表">设置选项值列表</h6>

<p>仅用于<code class="highlighter-rouge">xmake f --menu</code>的图形菜单配置时，提供选项值列表供用户快速选择使用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"b"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_values</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">)</span>
</code></pre>
</div>

<p>效果图如下：</p>

<p><img src="/assets/img/manual/option_set_values.png" width="60%" /></p>

<h5 id="optionset_default">option:set_default</h5>

<h6 id="设置选项默认值">设置选项默认值</h6>

<p>在没有通过<code class="highlighter-rouge">xmake f --option=[y|n}</code>等命令修改选项值的时候，这个选项本身也是有个默认值的，可以通过这个接口来设置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- 默认禁用这个选项</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
</code></pre>
</div>

<p>选项的值不仅支持boolean类型，也可以是字符串类型，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"value"</span><span class="p">)</span>
</code></pre>
</div>

<table>
  <thead>
    <tr>
      <th>值类型</th>
      <th>描述</th>
      <th>配置</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>boolean</td>
      <td>一般用作参数开关，值范围：<code class="highlighter-rouge">true/false</code></td>
      <td><code class="highlighter-rouge">xmake f --optionname=[y/n/yes/no/true/false]</code></td>
    </tr>
    <tr>
      <td>string</td>
      <td>可以是任意字符串，一般用于模式判断</td>
      <td><code class="highlighter-rouge">xmake f --optionname=value</code></td>
    </tr>
  </tbody>
</table>

<p>如果是<code class="highlighter-rouge">boolean</code>值的选项，可以通过<a href="#is_option">is_option</a>来进行判断，选项是否被启用。</p>

<p>如果是<code class="highlighter-rouge">string</code>类型的选项，可以在内建变量中直接使用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个路径配置选项，默认使用临时目录</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"rootdir"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- 添加指定选项目录中的源文件</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"$(rootdir)/*.c"</span><span class="p">)</span>
</code></pre>
</div>

<p>其中，<code class="highlighter-rouge">$(rootdir)</code> 就是自定义的选项内建变量，通过手动配置，可以动态修改它的值：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f --rootdir<span class="o">=</span>~/projectdir/src
<span class="gp">$ </span>xmake
</code></pre>
</div>

<p>给这个<code class="highlighter-rouge">rootdir</code>选项指定一个其他的源码目录路径，然后编译。</p>

<p>选项的检测行为：</p>

<table>
  <thead>
    <tr>
      <th>default值</th>
      <th>检测行为</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>没有设置</td>
      <td>优先手动配置修改，默认禁用，否则自动检测，可根据手动传入的值类型，自动切换boolean和string类型</td>
    </tr>
    <tr>
      <td>false</td>
      <td>开关选项，不自动检测，默认禁用，可手动配置修改</td>
    </tr>
    <tr>
      <td>true</td>
      <td>开关选项，不自动检测，默认启用，可手动配置修改</td>
    </tr>
    <tr>
      <td>string类型</td>
      <td>无开关状态，不自动检测，可手动配置修改，一般用于配置变量传递</td>
    </tr>
  </tbody>
</table>

<h5 id="optionset_showmenu">option:set_showmenu</h5>

<h6 id="设置是否启用菜单显示">设置是否启用菜单显示</h6>

<p>如果设置为<code class="highlighter-rouge">true</code>，那么在<code class="highlighter-rouge">xmake f --help</code>里面就会出现这个选项，也就能通过<code class="highlighter-rouge">xmake f --optionname=xxx</code>进行配置，否则只能在<code class="highlighter-rouge">xmake.lua</code>内部使用，无法手动配置修改。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
</code></pre>
</div>

<p>设置为启用菜单后，执行<code class="highlighter-rouge">xmake f --help</code>可以看到，帮助菜单里面多了一项：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Options:
    ...

    --test=TEST
</code></pre>
</div>

<h5 id="optionset_category">option:set_category</h5>

<h6 id="设置选项分类仅用于菜单显示">设置选项分类，仅用于菜单显示</h6>

<p>这个是个可选配置，仅用于在帮助菜单中，进行分类显示选项，同一类别的选项，会在同一个分组里面显示，这样菜单看起来更加的美观。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"demo1"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>

<span class="n">option</span><span class="p">(</span><span class="s2">"demo2"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
</code></pre>
</div>

<p>这里四个选项分别归类于两个分组：<code class="highlighter-rouge">test</code>和<code class="highlighter-rouge">demo</code>，那么显示的布局类似这样：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code>Options:
    ...

    --test1<span class="o">=</span>TEST1
    --test2<span class="o">=</span>TEST2
 
    --demo1<span class="o">=</span>DEMO1
    --demo2<span class="o">=</span>DEMO2
</code></pre>
</div>

<p>这个接口，仅仅是为了调整显示布局，更加美观而已，没其他用途。</p>

<p>在2.1.9版本中，可以通过category设置分级路径名<code class="highlighter-rouge">set_category("root/submenu/submenu2")</code>，来配置<code class="highlighter-rouge">xmake f --menu</code>的图形菜单界面，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 'boolean' option</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"test1"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"root menu/test1"</span><span class="p">)</span>

<span class="c1">-- 'choice' option with values: "a", "b", "c"</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"test2"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span>
    <span class="n">set_values</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"root menu/test2"</span><span class="p">)</span>

<span class="c1">-- 'string' option</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"test3"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"xx"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"root menu/test3/test3"</span><span class="p">)</span>

<span class="c1">-- 'number' option</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"test4"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_category</span><span class="p">(</span><span class="s2">"root menu/test4"</span><span class="p">)</span>
</code></pre>
</div>

<p>上述配置最后显示的菜单界面路径结构：</p>

<ul>
  <li>root menu
    <ul>
      <li>test1</li>
      <li>test2</li>
      <li>test3
        <ul>
          <li>test3</li>
        </ul>
      </li>
      <li>test4</li>
    </ul>
  </li>
</ul>

<p>效果图如下：</p>

<p><img src="/assets/img/manual/option_set_category.gif" width="60%" /></p>

<h5 id="optionset_description">option:set_description</h5>

<h6 id="设置菜单显示描述">设置菜单显示描述</h6>

<p>设置选项菜单显示时，右边的描述信息，用于帮助用户更加清楚的知道这个选项的用途，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_description</span><span class="p">(</span><span class="s2">"Enable or disable test"</span><span class="p">)</span>
</code></pre>
</div>

<p>生成的菜单内容如下：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Options:
    ...

    --test=TEST                       Enable or disable test (default: false)
</code></pre>
</div>

<p>这个接口也支持多行显示，输出更加详细的描述信息，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"mode"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="s2">"debug"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">set_description</span><span class="p">(</span><span class="s2">"Set build mode"</span><span class="p">,</span>
                    <span class="s2">"    - debug"</span><span class="p">,</span>
                    <span class="s2">"    - release"</span><span class="p">,</span>
                    <span class="s2">"    - profile"</span><span class="p">)</span>
</code></pre>
</div>

<p>生成的菜单内容如下：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Options:
    ...

    --mode=MODE                       Set build mode (default: debug)
                                          - debug
                                          - release
                                          - profile
</code></pre>
</div>

<p>看到这个菜单，用户就能清楚地知道，定义的这个<code class="highlighter-rouge">mode</code>选项的具体用处，以及如何使用了：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake f --mode<span class="o">=</span>release
</code></pre>
</div>

<h5 id="optionadd_bindings">option:add_bindings</h5>

<h6 id="添加正向关联选项同步启用和禁用">添加正向关联选项，同步启用和禁用</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。
</p>

<p>绑定关联选项，例如我想在命令行中配置一个<code class="highlighter-rouge">smallest</code>的参数：<code class="highlighter-rouge">xmake f --smallest=y</code></p>

<p>这个时候，需要同时禁用多个其他的选项开关，来禁止编译多个模块，就是这个需求，相当于一个选项 与其他 多个选项之间 是有联动效应的。</p>

<p>而这个接口就是用来设置需要正向绑定的一些关联选项，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义选项开关: --smallest=y|n</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"smallest"</span><span class="p">)</span>

    <span class="c1">-- 添加正向绑定，如果smallest被启用，下面的所有选项开关也会同步被启用</span>
    <span class="n">add_bindings</span><span class="p">(</span><span class="s2">"nozip"</span><span class="p">,</span> <span class="s2">"noxml"</span><span class="p">,</span> <span class="s2">"nojson"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="optionadd_rbindings">option:add_rbindings</h5>

<h6 id="添加逆向关联选项同步启用和禁用">添加逆向关联选项，同步启用和禁用</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。
</p>

<p>逆向绑定关联选项，被关联选项的开关状态是相反的。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义选项开关: --smallest=y|n</span>
<span class="n">option</span><span class="p">(</span><span class="s2">"smallest"</span><span class="p">)</span>

    <span class="c1">-- 添加反向绑定，如果smallest被启用，下面的所有模块全部禁用</span>
    <span class="n">add_rbindings</span><span class="p">(</span><span class="s2">"xml"</span><span class="p">,</span> <span class="s2">"zip"</span><span class="p">,</span> <span class="s2">"asio"</span><span class="p">,</span> <span class="s2">"regex"</span><span class="p">,</span> <span class="s2">"object"</span><span class="p">,</span> <span class="s2">"thread"</span><span class="p">,</span> <span class="s2">"network"</span><span class="p">,</span> <span class="s2">"charset"</span><span class="p">,</span> <span class="s2">"database"</span><span class="p">)</span>
    <span class="n">add_rbindings</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">,</span> <span class="s2">"mysql"</span><span class="p">,</span> <span class="s2">"sqlite3"</span><span class="p">,</span> <span class="s2">"openssl"</span><span class="p">,</span> <span class="s2">"polarssl"</span><span class="p">,</span> <span class="s2">"pcre2"</span><span class="p">,</span> <span class="s2">"pcre"</span><span class="p">,</span> <span class="s2">"base"</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
需要注意的是，命令行配置是有顺序的，你可以先通过启用smallest禁用所有模块，然后添加其他选项，逐一启用。
</p>

<p>例如：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code>-- 禁用所有模块，然后仅仅启用xml和zip模块
<span class="gp">$ </span>xmake f --smallest<span class="o">=</span>y --xml<span class="o">=</span>y --zip<span class="o">=</span>y
</code></pre>
</div>

<h5 id="optionadd_links">option:add_links</h5>

<h6 id="添加链接库检测">添加链接库检测</h6>

<p>如果指定的链接库检测通过，此选项将被启用，并且对应关联的target会自动加上此链接，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">add_links</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
    <span class="n">add_linkdirs</span><span class="p">(</span><span class="s2">"/usr/local/lib"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果检测通过，<code class="highlighter-rouge">test</code>目标编译的时候就会自动加上：<code class="highlighter-rouge">-L/usr/local/lib -lpthread</code> 编译选项</p>

<h5 id="optionadd_linkdirs">option:add_linkdirs</h5>

<h6 id="添加链接库检测时候需要的搜索目录">添加链接库检测时候需要的搜索目录</h6>

<p>这个是可选的，一般系统库不需要加这个，也能检测通过，如果确实没找到，可以自己追加搜索目录，提高检测通过率。具体使用见：<a href="#optionadd_links">add_links</a></p>

<h5 id="optionadd_rpathdirs">option:add_rpathdirs</h5>

<h6 id="添加程序运行时动态库的加载搜索目录">添加程序运行时动态库的加载搜索目录</h6>

<p>在选项通过检测后，会自动添加到对应的target上去，具体使用见：<a href="#targetadd_rpathdirs">target.add_rpathdirs</a>。</p>

<h5 id="optionadd_cincludes">option:add_cincludes</h5>

<h6 id="添加c头文件检测">添加c头文件检测</h6>

<p>如果c头文件检测通过，此选项将被启用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">add_cincludes</span><span class="p">(</span><span class="s2">"pthread.h"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"ENABLE_PTHREAD"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
</code></pre>
</div>

<p>此选项检测是否存在<code class="highlighter-rouge">pthread.h</code>的头文件，如果检测通过那么<code class="highlighter-rouge">test</code>目标程序将会加上<code class="highlighter-rouge">ENABLE_PTHREAD</code>的宏定义。</p>

<p>如果想要更加灵活的检测，可以通过<a href="#detect-has_cincludes">lib.detect.has_cincludes</a>在<a href="#optionon_check">option.on_check</a>中去实现。</p>

<h5 id="optionadd_cxxincludes">option:add_cxxincludes</h5>

<h6 id="添加c头文件检测-1">添加c++头文件检测</h6>

<p>与<a href="#optionadd_cincludes">add_cincludes</a>类似，只是检测的头文件类型是c++头文件。</p>

<h5 id="optionadd_ctypes">option:add_ctypes</h5>

<h6 id="添加c类型检测">添加c类型检测</h6>

<p>如果c类型检测通过，此选项将被启用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">add_cincludes</span><span class="p">(</span><span class="s2">"wchar_t"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"HAVE_WCHAR"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"wchar"</span><span class="p">)</span>
</code></pre>
</div>

<p>此选项检测是否存在<code class="highlighter-rouge">wchar_t</code>的类型，如果检测通过那么<code class="highlighter-rouge">test</code>目标程序将会加上<code class="highlighter-rouge">HAVE_WCHAR</code>的宏定义。</p>

<p>如果想要更加灵活的检测，可以通过<a href="#detect-has_ctypes">lib.detect.has_ctypes</a>在<a href="#optionon_check">option.on_check</a>中去实现。</p>

<h5 id="optionadd_cxxtypes">option:add_cxxtypes</h5>

<h6 id="添加c类型检测-1">添加c++类型检测</h6>

<p>与<a href="#optionadd_ctypes">add_ctypes</a>类似，只是检测的类型是c++类型。</p>

<h5 id="optionadd_csnippet">option:add_csnippet</h5>

<h6 id="添加c代码片段检测">添加c代码片段检测</h6>

<p>如果现有的<a href="#optionadd_ctypes">add_ctypes</a>, <a href="#optionadd_cfuncs">add_cfuncs</a>等不能满足当前的检测需求，
可以用这个接口实现更加定制化检测一些编译器特性检测，具体见: <a href="#optionadd_cxxsnippet">add_cxxsnippet</a>。</p>

<h5 id="optionadd_cxxsnippet">option:add_cxxsnippet</h5>

<h6 id="添加c代码片段检测-1">添加c++代码片段检测</h6>

<p>可以用这个接口实现更加定制化检测一些编译器特性检测，尤其是c++的各种特性的检测支持，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"constexpr"</span><span class="p">)</span>
    <span class="n">add_cxxsnippet</span><span class="p">(</span><span class="s2">"constexpr int f(int x) { int sum=0; for (int i=0; i&lt;=x; ++i) sum += i; return sum; } constexpr int x = f(5);  static_assert(x == 15);"</span><span class="p">)</span>
</code></pre>
</div>

<p>上述代码，实现对c++的constexpr特性的检测，如果检测通过，则启用constexpr选项，当然这里只是个例子。</p>

<p>对于编译器特性的检测，有更加方便高效的检测模块，提供更强大的检测支持，具体见：<a href="#compiler-has_features">compiler.has_features</a>和<a href="#detect-check_cxsnippets">detect.check_cxsnippets</a></p>

<p>如果想要更加灵活的检测，可以通过<a href="#detect-check_cxsnippets">lib.detect.check_cxsnippets</a>在<a href="#optionon_check">option.on_check</a>中去实现。</p>

<h5 id="optionadd_defines_if_ok">option:add_defines_if_ok</h5>

<h6 id="如果检测选项通过则添加宏定义">如果检测选项通过，则添加宏定义</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_defines](#targetadd_defines)接口代替。
</p>

<p>检测选项通过后才会被设置，具体使用见<a href="#optionadd_cincludes">add_cincludes</a>中的例子。</p>

<h5 id="optionadd_defines_h_if_ok">option:add_defines_h_if_ok</h5>

<h6 id="如果检测选项通过则添加宏定义到配置头文件">如果检测选项通过，则添加宏定义到配置头文件</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_defines_h](#targetadd_defines_h)接口代替。
</p>

<p>跟<a href="#optionadd_defines_if_ok">add_defines_if_ok</a>类似，只是检测通过后，会在<code class="highlighter-rouge">config.h</code>头文件中自动加上被设置的宏定义。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
    <span class="n">set_default</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
    <span class="n">add_cincludes</span><span class="p">(</span><span class="s2">"pthread.h"</span><span class="p">)</span>
    <span class="n">add_defines_h_if_ok</span><span class="p">(</span><span class="s2">"ENABLE_PTHREAD"</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_options</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
</code></pre>
</div>

<p>通过后，会在<code class="highlighter-rouge">config.h</code>中加上：</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="cp">#define ENABLE_PTHREAD 1
</span></code></pre>
</div>

<p>具体<code class="highlighter-rouge">config.h</code>如何设置，见：<a href="#targetset_config_h">set_config_h</a></p>

<h5 id="optionadd_undefines_if_ok">option:add_undefines_if_ok</h5>

<h6 id="如果检测选项通过则取消宏定义">如果检测选项通过，则取消宏定义</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_undefines](#targetadd_undefines)接口代替。
</p>

<p>跟<a href="#optionadd_defines_if_ok">add_defines_if_ok</a>类似，只是检测通过后，取消被设置的宏定义。</p>

<h5 id="optionadd_undefines_h_if_ok">option:add_undefines_h_if_ok</h5>

<h6 id="如果检测选项通过则在配置头文件中取消宏定义">如果检测选项通过，则在配置头文件中取消宏定义</h6>

<p class="tip">
2.1.5版本之后已废弃，请用[add_undefines_h](#targetadd_undefines_h)接口代替。
</p>

<p>跟<a href="#optionadd_defines_h_if_ok">add_defines_h_if_ok</a>类似，只是检测通过后，会在<code class="highlighter-rouge">config.h</code>中取消被设置的宏定义。</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="cp">#undef DEFINED_MACRO
</span></code></pre>
</div>

<p>具体<code class="highlighter-rouge">config.h</code>如何设置，见：<a href="#targetset_config_h">set_config_h</a></p>

<h4 id="plugin-and-task">Plugin and Task</h4>

<p>xmake可以实现自定义任务或者插件，其两者的核心就是<code class="highlighter-rouge">task</code>任务，其两者实际上是一样的，xmake的插件都是用<code class="highlighter-rouge">task</code>实现的。</p>

<p>本质上都是任务，只是<a href="#taskset_category">set_category</a>分类不同而已。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#task">task</a></td>
      <td>定义插件或者任务</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#task_end">task_end</a></td>
      <td>结束定义插件或任务</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#taskset_menu">set_menu</a></td>
      <td>设置任务菜单</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#taskset_category">set_category</a></td>
      <td>设置任务类别</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#taskon_run">on_run</a></td>
      <td>设置任务运行脚本</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h5 id="task">task</h5>

<h6 id="定义插件或者任务">定义插件或者任务</h6>

<p><code class="highlighter-rouge">task</code>域用于描述一个自定义的任务实现，与<a href="#target">target</a>和<a href="#option">option</a>同级。</p>

<p>例如，这里定义一个最简单的任务：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>

    <span class="c1">-- 设置运行脚本</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>这个任务只需要打印<code class="highlighter-rouge">hello xmake!</code>，那如何来运行呢？</p>

<p>由于这里没有使用<a href="#taskset_menu">set_menu</a>设置菜单，因此这个任务只能再<code class="highlighter-rouge">xmake.lua</code>的自定义脚本或者其他任务内部调用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
 
        <span class="c1">-- 导入task模块</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.task"</span><span class="p">)</span>

        <span class="c1">-- 运行hello任务</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>在构建完<code class="highlighter-rouge">test</code>目标后运行<code class="highlighter-rouge">hello</code>任务。</p>

<h5 id="task_end">task_end</h5>

<h6 id="结束定义插件或任务">结束定义插件或任务</h6>

<p>这是一个可选api，显示离开选项作用域，用法和<a href="#target_end">target_end</a>类似。</p>

<h5 id="taskset_menu">task:set_menu</h5>

<h6 id="设置任务菜单">设置任务菜单</h6>

<p>通过设置一个菜单，这个任务就可以开放给用户自己通过命令行手动调用，菜单的设置如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">)</span>

    <span class="c1">-- 设置运行脚本</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>

        <span class="c1">-- 导入参数选项模块</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>

        <span class="c1">-- 初始化颜色模式</span>
        <span class="kd">local</span> <span class="n">modes</span> <span class="o">=</span> <span class="s2">""</span>
        <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">mode</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"bright"</span><span class="p">,</span> <span class="s2">"dim"</span><span class="p">,</span> <span class="s2">"blink"</span><span class="p">,</span> <span class="s2">"reverse"</span><span class="p">})</span> <span class="k">do</span>
            <span class="k">if</span> <span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="n">mode</span><span class="p">)</span> <span class="k">then</span>
                <span class="n">modes</span> <span class="o">=</span> <span class="n">modes</span> <span class="o">..</span> <span class="s2">" "</span> <span class="o">..</span> <span class="n">mode</span> 
            <span class="k">end</span>
        <span class="k">end</span>

        <span class="c1">-- 获取参数内容并且显示信息</span>
        <span class="n">cprint</span><span class="p">(</span><span class="s2">"${ %s%s }%s"</span><span class="p">,</span> <span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"color"</span><span class="p">),</span> <span class="n">modes</span><span class="p">,</span> <span class="nb">table.concat</span><span class="p">(</span><span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"contents"</span><span class="p">)</span> <span class="ow">or</span> <span class="p">{},</span> <span class="s2">" "</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>

    <span class="c1">-- 设置插件的命令行选项，这里没有任何参数选项，仅仅显示插件描述</span>
    <span class="n">set_menu</span> <span class="p">{</span>
                <span class="c1">-- 设置菜单用法</span>
                <span class="n">usage</span> <span class="o">=</span> <span class="s2">"xmake echo [options]"</span>

                <span class="c1">-- 设置菜单描述</span>
            <span class="p">,</span>   <span class="n">description</span> <span class="o">=</span> <span class="s2">"Echo the given info!"</span>

                <span class="c1">-- 设置菜单选项，如果没有选项，可以设置为{}</span>
            <span class="p">,</span>   <span class="n">options</span> <span class="o">=</span> 
                <span class="p">{</span>
                    <span class="c1">-- 设置k模式作为key-only型bool参数</span>
                    <span class="p">{</span><span class="s1">'b'</span><span class="p">,</span> <span class="s2">"bright"</span><span class="p">,</span>     <span class="s2">"k"</span><span class="p">,</span>  <span class="kc">nil</span><span class="p">,</span>       <span class="s2">"Enable bright."</span>               <span class="p">}</span>      
                <span class="p">,</span>   <span class="p">{</span><span class="s1">'d'</span><span class="p">,</span> <span class="s2">"dim"</span><span class="p">,</span>        <span class="s2">"k"</span><span class="p">,</span>  <span class="kc">nil</span><span class="p">,</span>       <span class="s2">"Enable dim."</span>                  <span class="p">}</span>      
                <span class="p">,</span>   <span class="p">{</span><span class="s1">'-'</span><span class="p">,</span> <span class="s2">"blink"</span><span class="p">,</span>      <span class="s2">"k"</span><span class="p">,</span>  <span class="kc">nil</span><span class="p">,</span>       <span class="s2">"Enable blink."</span>                <span class="p">}</span>      
                <span class="p">,</span>   <span class="p">{</span><span class="s1">'r'</span><span class="p">,</span> <span class="s2">"reverse"</span><span class="p">,</span>    <span class="s2">"k"</span><span class="p">,</span>  <span class="kc">nil</span><span class="p">,</span>       <span class="s2">"Reverse color."</span>               <span class="p">}</span>      

                    <span class="c1">-- 菜单显示时，空白一行</span>
                <span class="p">,</span>   <span class="p">{}</span>

                    <span class="c1">-- 设置kv作为key-value型参数，并且设置默认值：black</span>
                <span class="p">,</span>   <span class="p">{</span><span class="s1">'c'</span><span class="p">,</span> <span class="s2">"color"</span><span class="p">,</span>      <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"black"</span><span class="p">,</span>   <span class="s2">"Set the output color."</span>
                                                     <span class="p">,</span>   <span class="s2">"    - red"</span>   
                                                     <span class="p">,</span>   <span class="s2">"    - blue"</span>
                                                     <span class="p">,</span>   <span class="s2">"    - yellow"</span>
                                                     <span class="p">,</span>   <span class="s2">"    - green"</span>
                                                     <span class="p">,</span>   <span class="s2">"    - magenta"</span>
                                                     <span class="p">,</span>   <span class="s2">"    - cyan"</span> 
                                                     <span class="p">,</span>   <span class="s2">"    - white"</span>                  <span class="p">}</span>

                    <span class="c1">-- 设置`vs`作为values多值型参数，还有`v`单值类型</span>
                    <span class="c1">-- 一般放置在最后，用于获取可变参数列表</span>
                <span class="p">,</span>   <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"contents"</span><span class="p">,</span>   <span class="s2">"vs"</span><span class="p">,</span> <span class="kc">nil</span><span class="p">,</span>       <span class="s2">"The info contents."</span>           <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span> 
</code></pre>
</div>

<p>定义完这个任务后，执行<code class="highlighter-rouge">xmake --help</code>，就会多出一个任务项来：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Tasks:

    ...

    echo                    Echo the given info!
</code></pre>
</div>

<p>如果通过<a href="#taskset_category">set_category</a>设置分类为<code class="highlighter-rouge">plugin</code>，那么这个任务就是一个插件了：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Plugins:

    ...

    echo                    Echo the given info!
</code></pre>
</div>

<p>想要手动运行这个任务，可以执行：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake <span class="nb">echo </span>hello xmake!
</code></pre>
</div>

<p>就行了，如果要看这个任务定义的菜单，只需要执行：<code class="highlighter-rouge">xmake echo [-h|--help]</code>，显示结果如下：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code>Usage: <span class="nv">$xmake</span> <span class="nb">echo</span> <span class="o">[</span>options]

Echo the given info!

Options: 
    -v, --verbose                          Print lots of verbose information.
        --backtrace                        Print backtrace information <span class="k">for </span>debugging.
        --profile                          Print performance data <span class="k">for </span>debugging.
        --version                          Print the version number and exit.
    -h, --help                             Print this <span class="nb">help </span>message and exit.
                                           
    -F FILE, --file<span class="o">=</span>FILE                   Read a given xmake.lua file.
    -P PROJECT, --project<span class="o">=</span>PROJECT          Change to the given project directory.
                                           Search priority:
                                               1. The Given Command Argument
                                               2. The Envirnoment Variable: XMAKE_PROJECT_DIR
                                               3. The Current Directory
                                           
    -b, --bright                           Enable bright.
    -d, --dim                              Enable dim.
    --, --blink                            Enable blink.
    -r, --reverse                          Reverse color.
                                           
    -c COLOR, --color<span class="o">=</span>COLOR                Set the output color. <span class="o">(</span>default: black<span class="o">)</span>
                                               - red
                                               - blue
                                               - yellow
                                               - green
                                               - magenta
                                               - cyan
                                               - white
                                           
    contents ...                           The info contents.
</code></pre>
</div>

<p class="tip">
其中菜单最开头的部分选项，是xmake内置的常用选项，基本上每个任务都会用到，不需要自己额外定义，简化菜单定义。
</p>

<p>下面，我们来实际运行下这个任务，例如我要显示红色的<code class="highlighter-rouge">hello xmake!</code>，只需要：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake <span class="nb">echo</span> -c red hello xmake!
</code></pre>
</div>

<p>也可以使用选项全名，并且加上高亮：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>xmake <span class="nb">echo</span> --color<span class="o">=</span>red --bright hello xmake!
</code></pre>
</div>

<p>最后面的可变参数列表，在<code class="highlighter-rouge">run</code>脚本中通过<code class="highlighter-rouge">option.get("contents")</code>获取，返回的是一个<code class="highlighter-rouge">table</code>类型的数组。</p>

<h5 id="taskset_category">task:set_category</h5>

<h6 id="设置任务类别">设置任务类别</h6>

<p>仅仅用于菜单的分组显示，当然插件默认会用<code class="highlighter-rouge">plugin</code>，内置任务默认会用：<code class="highlighter-rouge">action</code>，但也仅仅只是个约定。</p>

<p class="tips">
你可以使用任何自己定义的名字，相同名字会分组归类到一起显示，如果设置为`plugin`，就会显示到xmake的Plugins分组中去。
</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">Plugins</span><span class="p">:</span> 
    <span class="n">l</span><span class="p">,</span> <span class="n">lua</span>               <span class="n">Run</span> <span class="n">the</span> <span class="n">lua</span> <span class="n">script</span><span class="p">.</span>
    <span class="n">m</span><span class="p">,</span> <span class="n">macro</span>             <span class="n">Run</span> <span class="n">the</span> <span class="n">given</span> <span class="n">macro</span><span class="p">.</span>
       <span class="n">doxygen</span>           <span class="n">Generate</span> <span class="n">the</span> <span class="n">doxygen</span> <span class="n">document</span><span class="p">.</span>
       <span class="n">project</span>           <span class="n">Generate</span> <span class="n">the</span> <span class="n">project</span> <span class="n">file</span><span class="p">.</span>
       <span class="n">hello</span>             <span class="n">Hello</span> <span class="n">xmake</span><span class="err">!</span>
       <span class="n">app2ipa</span>           <span class="n">Generate</span> <span class="p">.</span><span class="n">ipa</span> <span class="n">file</span> <span class="n">from</span> <span class="n">the</span> <span class="n">given</span> <span class="p">.</span><span class="n">app</span>
       <span class="n">echo</span>              <span class="n">Echo</span> <span class="n">the</span> <span class="n">given</span> <span class="n">info</span><span class="err">!</span>
</code></pre>
</div>

<p>如果没有调用这个接口设置分类，默认使用<code class="highlighter-rouge">Tasks</code>分组显示，代表普通任务。</p>

<h5 id="taskon_run">task:on_run</h5>

<h6 id="设置任务运行脚本">设置任务运行脚本</h6>

<p>可以有两种设置方式，最简单的就是设置内嵌函数：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>

    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>这种对于小任务很方便，也很简洁，但是对于大型任务就不太适用了，例如插件等，需要复杂的脚本支持。</p>

<p>这个时候就需要独立的模块文件来设置运行脚本，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="s2">"main"</span><span class="p">)</span>
</code></pre>
</div>

<p>这里的<code class="highlighter-rouge">main</code>设置为脚本运行主入口模块，文件名为<code class="highlighter-rouge">main.lua</code>，放在定义<code class="highlighter-rouge">task</code>的<code class="highlighter-rouge">xmake.lua</code>的同目录下，当然你可以起其他文件名。</p>

<p>目录结构如下：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>projectdir
    - xmake.lua
    - main.lua
</code></pre>
</div>

<p><code class="highlighter-rouge">main.lua</code>里面内容如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>就是一个简单的带<code class="highlighter-rouge">main</code>主函数的脚本文件，你可以通过<a href="#import">import</a>导入各种扩展模块，实现复杂功能，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 导入参数选项模块</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>

<span class="c1">-- 入口函数</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>

    <span class="c1">-- 获取参数内容</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"color: %s"</span><span class="p">,</span> <span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"color"</span><span class="p">))</span>
<span class="k">end</span>
</code></pre>
</div>

<p>你也可以在当前目录下，创建多个自定义的模块文件，通过<a href="#import">import</a>导入后使用，例如：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>projectdir
    - xmake.lua
    - main.lua
    - module.lua
</code></pre>
</div>

<p><code class="highlighter-rouge">module.lua</code>的内容如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个导出接口</span>
<span class="k">function</span> <span class="nf">hello</span><span class="p">()</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p class="tip">
私有接口，通过`_hello`带下滑线前缀命名，这样导入的模块就不会包含此接口，只在模块自身内部使用。
</p>

<p>然后在<code class="highlighter-rouge">main.lua</code>进行调用：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"module"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
    <span class="n">module</span><span class="p">.</span><span class="n">hello</span><span class="p">()</span>
<span class="k">end</span>
</code></pre>
</div>

<p>更多模块介绍见：<a href="#内置模块">内置模块</a>和<a href="扩展模块">扩展模块</a></p>

<p>其中，<code class="highlighter-rouge">main(...)</code>中参数，是通过<code class="highlighter-rouge">task.run</code>指定的，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">,</span> <span class="p">{</span><span class="n">color</span><span class="o">=</span><span class="s2">"red"</span><span class="p">},</span> <span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">,</span> <span class="n">arg3</span><span class="p">)</span>
</code></pre>
</div>

<p>里面的<code class="highlighter-rouge">arg1, arg2</code>这些就是传入<code class="highlighter-rouge">hello</code>任务<code class="highlighter-rouge">main(...)</code>入口的参数列表，而<code class="highlighter-rouge"><span class="p">{</span><span class="err">color=</span><span class="nt">"red"</span><span class="err">}</span></code>用来指定任务菜单中的参数选项。</p>

<p>更加详细的<code class="highlighter-rouge">task.run</code>描述，见：<a href="#task-run">task.run</a></p>

<h4 id="custom-rule">Custom Rule</h4>

<p>在2.1.9版本之后，xmake不仅原生内置支持多种语言文件的构建，而且还可以通过自定义构建规则，让用户自己来实现复杂的未知文件构建。</p>

<p>我们可以通过预先设置规则支持的文件后缀，来扩展其他文件的构建支持：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个markdown文件的构建规则</span>
<span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".md"</span><span class="p">,</span> <span class="s2">".markdown"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetdir</span><span class="p">(),</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">)</span> <span class="o">..</span> <span class="s2">".html"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    
    <span class="c1">-- 使test目标支持markdown文件的构建规则</span>
    <span class="n">add_rules</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>

    <span class="c1">-- 添加markdown文件的构建</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.md"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.markdown"</span><span class="p">)</span>
</code></pre>
</div>

<p>我们也可以指定某些零散的其他文件作为markdown规则来处理：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- ...</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test/*.md.in"</span><span class="p">,</span> <span class="p">{</span><span class="n">rule</span> <span class="o">=</span> <span class="s2">"markdown"</span><span class="p">})</span>
</code></pre>
</div>

<p class="tips">
通过`add_files("*.md", {rule = "markdown"})`方式指定的规则，优先级高于`add_rules("markdown")`设置的规则。
</p>

<p>我们还可以实现规则的级联构建，例如在构建man规则后，继续调用markdown规则，实现级联构建：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"man"</span><span class="p">)</span>
    <span class="n">add_imports</span><span class="p">(</span><span class="s2">"core.project.rule"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="n">rule</span><span class="p">.</span><span class="n">build</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>对于有些文件，需要支持多文件构建生成单一对象的模式，可以通过<a href="#ruleon_build_all">on_build_all</a>来实现：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"man"</span><span class="p">)</span>
    <span class="n">on_build_all</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefiles</span><span class="p">)</span>
        <span class="c1">-- build some source files</span>
        <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">sourcefile</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">sourcefiles</span><span class="p">)</span> <span class="k">do</span>
            <span class="c1">-- ...</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- ...</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/test/*.doc.in"</span><span class="p">,</span> <span class="p">{</span><span class="n">rule</span> <span class="o">=</span> <span class="s2">"man"</span><span class="p">})</span>
</code></pre>
</div>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#rule">rule</a></td>
      <td>定义规则</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleadd_imports">add_imports</a></td>
      <td>为所有自定义脚本预先导入扩展模块</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleset_extensions">set_extensions</a></td>
      <td>设置规则支持的文件扩展类型</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_build">on_build</a></td>
      <td>自定义编译脚本</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_clean">on_clean</a></td>
      <td>自定义清理脚本</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_package">on_package</a></td>
      <td>自定义打包脚本</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_install">on_install</a></td>
      <td>自定义安装脚本</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_uninstall">on_uninstall</a></td>
      <td>自定义卸载脚本</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_build_all">on_build_all</a></td>
      <td>自定义编译脚本, 实现多文件构建</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_clean_all">on_clean_all</a></td>
      <td>自定义清理脚本，实现多文件清理</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_package_all">on_package_all</a></td>
      <td>自定义打包脚本，实现多文件打包</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_install_all">on_install_all</a></td>
      <td>自定义安装脚本，实现多文件安装</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#ruleon_uninstall_all">on_uninstall_all</a></td>
      <td>自定义卸载脚本，实现多文件卸载</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#rule_end">rule_end</a></td>
      <td>结束定义规则</td>
      <td>&gt;= 2.1.9</td>
    </tr>
  </tbody>
</table>

<h5 id="rule">rule</h5>

<h6 id="定义规则">定义规则</h6>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".md"</span><span class="p">,</span> <span class="s2">".markdown"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetdir</span><span class="p">(),</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">)</span> <span class="o">..</span> <span class="s2">".html"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="ruleadd_imports">rule:add_imports</h5>

<h6 id="为所有自定义脚本预先导入扩展模块">为所有自定义脚本预先导入扩展模块</h6>

<p>使用方式和说明请见：<a href="#targetadd_imports">target:add_imports</a>，用法相同。</p>

<h5 id="ruleset_extensions">rule:set_extensions</h5>

<h6 id="设置规则支持的文件扩展类型">设置规则支持的文件扩展类型</h6>

<p>通过设置支持的扩展文件类型，将规则应用于带这些后缀的文件上，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 定义一个markdown文件的构建规则</span>
<span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">set_extensions</span><span class="p">(</span><span class="s2">".md"</span><span class="p">,</span> <span class="s2">".markdown"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetdir</span><span class="p">(),</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">)</span> <span class="o">..</span> <span class="s2">".html"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    
    <span class="c1">-- 使test目标支持markdown文件的构建规则</span>
    <span class="n">add_rules</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>

    <span class="c1">-- 添加markdown文件的构建</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.md"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.markdown"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="ruleon_build">rule:on_build</h5>

<h6 id="自定义编译脚本">自定义编译脚本</h6>

<p>用于实现自定规则的构建脚本，每次处理一个源文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="c1">-- generate sourcefile to sourcefile.html</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="ruleon_clean">rule:on_clean</h5>

<h6 id="自定义清理脚本">自定义清理脚本</h6>

<p>用于实现自定规则的清理脚本，每次处理一个源文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_clean</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="c1">-- remove sourcefile.html</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：清理的文件可以通过源文件推算出来</p>

<h5 id="ruleon_package">rule:on_package</h5>

<h6 id="自定义打包脚本">自定义打包脚本</h6>

<p>用于实现自定规则的打包脚本，每次处理一个源文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_package</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="c1">-- package sourcefile.html</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：打包的文件可以通过源文件推算出来</p>

<h5 id="ruleon_install">rule:on_install</h5>

<h6 id="自定义安装脚本">自定义安装脚本</h6>

<p>用于实现自定规则的安装脚本，每次处理一个源文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="c1">-- install sourcefile.html</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：安装的文件可以通过源文件推算出来</p>

<h5 id="ruleon_uninstall">rule:on_uninstall</h5>

<h6 id="自定义卸载脚本">自定义卸载脚本</h6>

<p>用于实现自定规则的卸载脚本，每次处理一个源文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_uninstall</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">)</span>
        <span class="c1">-- uninstall sourcefile.html</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：卸载的文件可以通过源文件推算出来</p>

<h5 id="ruleon_build_all">rule:on_build_all</h5>

<h6 id="自定义编译脚本一次处理多个源文件">自定义编译脚本，一次处理多个源文件</h6>

<p>大部分的自定义构建规则，每次都是处理单独一个文件，输出一个目标文件，例如：a.c =&gt; a.o</p>

<p>但是，有些情况下，我们需要同时输入多个源文件一起构建生成一个目标文件，例如：a.c b.c d.c =&gt; x.o</p>

<p>对于这种情况，我们可以通过自定义这个脚本来实现：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"markdown"</span><span class="p">)</span>
    <span class="n">on_build_all</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefiles</span><span class="p">)</span>
        <span class="c1">-- build some source files</span>
        <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">sourcefile</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">sourcefiles</span><span class="p">)</span> <span class="k">do</span>
            <span class="c1">-- ...</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="ruleon_clean_all">rule:on_clean_all</h5>

<h6 id="自定义清理脚本一次处理多个源文件">自定义清理脚本，一次处理多个源文件</h6>

<p>可参考：<a href="#ruleon_clean">on_clean</a> 和 <a href="#ruleon_build_all">on_build_all</a>，使用方式类似。</p>

<h5 id="ruleon_package_all">rule:on_package_all</h5>

<h6 id="自定义打包脚本一次处理多个源文件">自定义打包脚本，一次处理多个源文件</h6>

<p>可参考：<a href="#ruleon_package">on_package</a> 和 <a href="#ruleon_build_all">on_build_all</a>，使用方式类似。</p>

<h5 id="ruleon_install_all">rule:on_install_all</h5>

<h6 id="自定义安装脚本一次处理多个源文件">自定义安装脚本，一次处理多个源文件</h6>

<p>可参考：<a href="#ruleon_install">on_install</a> 和 <a href="#ruleon_build_all">on_build_all</a>，使用方式类似。</p>

<h5 id="ruleon_uninstall_all">rule:on_uninstall_all</h5>

<h6 id="自定义卸载脚本一次处理多个源文件">自定义卸载脚本，一次处理多个源文件</h6>

<p>可参考：<a href="#ruleon_uninstall">on_uninstall</a> 和 <a href="#ruleon_build_all">on_build_all</a>，使用方式类似。</p>

<h5 id="rule_end">rule_end</h5>

<h6 id="结束定义规则">结束定义规则</h6>

<p>这个是可选的，如果想要手动结束rule的定义，可以调用它：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">rule</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="c1">-- ..</span>
<span class="n">rule_end</span><span class="p">()</span>
</code></pre>
</div>

<h4 id="extension-platforms">Extension Platforms</h4>

<p>xmake除了内置的一些构建平台，还可以自己扩展自定义构建平台，可以将自己实现的平台放置在以下目录即可, xmake会自动检测并且加载他们：</p>

<table>
  <thead>
    <tr>
      <th>平台目录</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>projectdir/.xmake/platforms</td>
      <td>当前工程的平台目录, 只对当前工程有效</td>
    </tr>
    <tr>
      <td>globaldir/.xmake/platforms</td>
      <td>全局配置的平台目录，当前主机全局有效</td>
    </tr>
    <tr>
      <td>installdir/xmake/platforms</td>
      <td>xmake安装后内置的平台目录</td>
    </tr>
  </tbody>
</table>

<p>用户可根据不同需求，将自定义的平台放置在对应的目录中。</p>

<p class="warning">
平台的扩展定义，尽量不要放到工程`xmake.lua`中去，新建一个单独的平台目录放置相关描述实现。
</p>

<p>平台描述的目录结构：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>platforms

    - myplat1
        - xmake.lua

    - myplat2
        - xmake.lua
</code></pre>
</div>

<p>其中<code class="highlighter-rouge">xmake.lua</code>为每个平台的主描述文件，相当于入口描述。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#platform">platform</a></td>
      <td>定义平台</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platform_end">platform_end</a></td>
      <td>结束定义平台</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#platformset_os">set_os</a></td>
      <td>设置平台系统</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformset_menu">set_menu</a></td>
      <td>设置平台菜单</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformset_hosts">set_hosts</a></td>
      <td>设置平台支持的主机环境</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformset_archs">set_archs</a></td>
      <td>设置平台支持的架构环境</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformset_tooldirs">set_tooldirs</a></td>
      <td>设置平台工具的搜索目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformon_load">on_load</a></td>
      <td>设置加载平台环境配置脚本</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformon_check">on_check</a></td>
      <td>设置平台工具的检测脚本</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#platformon_install">on_install</a></td>
      <td>设置平台相关的工程目标安装脚本</td>
      <td>&gt;= 2.0.5</td>
    </tr>
    <tr>
      <td><a href="#platformon_uninstall">on_uninstall</a></td>
      <td>设置平台相关的工程目标卸载脚本</td>
      <td>&gt;= 2.0.5</td>
    </tr>
  </tbody>
</table>

<h5 id="platform">platform</h5>

<h6 id="定义平台">定义平台</h6>

<p>自定义一个平台域，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span>
    
    <span class="c1">-- 设置操作系统</span>
    <span class="n">set_os</span><span class="p">(</span><span class="s2">"ios"</span><span class="p">)</span>

    <span class="c1">-- 设置主机环境</span>
    <span class="n">set_hosts</span><span class="p">(</span><span class="s2">"macosx"</span><span class="p">)</span>

    <span class="c1">-- 设置支持的架构</span>
    <span class="n">set_archs</span><span class="p">(</span><span class="s2">"armv7"</span><span class="p">,</span> <span class="s2">"armv7s"</span><span class="p">,</span> <span class="s2">"arm64"</span><span class="p">,</span> <span class="s2">"i386"</span><span class="p">,</span> <span class="s2">"x86_64"</span><span class="p">)</span>

    <span class="c1">-- 设置gcc, clang等平台相关工具的搜索目录</span>
    <span class="n">set_tooldirs</span><span class="p">(</span><span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">,</span> <span class="s2">"/opt/bin"</span><span class="p">,</span> <span class="s2">"/opt/local/bin"</span><span class="p">)</span>

    <span class="c1">-- 设置gcc，clang等工具的检测脚本文件</span>
    <span class="n">on_check</span><span class="p">(</span><span class="s2">"check"</span><span class="p">)</span>

    <span class="c1">-- 设置平台初始化加载脚本文件，如果实现不复杂的话，可以使用内嵌函数</span>
    <span class="n">on_load</span><span class="p">(</span><span class="s2">"load"</span><span class="p">)</span>

    <span class="c1">-- 设置平台的帮助菜单</span>
    <span class="n">set_menu</span> <span class="p">{</span>
                <span class="n">config</span> <span class="o">=</span> 
                <span class="p">{</span>   
                    <span class="p">{}</span>   
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_dir"</span><span class="p">,</span>      <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the xcode application directory"</span>   <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_sdkver"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the sdk version for xcode"</span>         <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"target_minver"</span><span class="p">,</span>  <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the target minimal version"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"mobileprovision"</span><span class="p">,</span><span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Provisioning Profile File"</span>     <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"codesign"</span><span class="p">,</span>       <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Indentity"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"entitlements"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Entitlements"</span>     <span class="p">}</span>
                <span class="p">}</span>

            <span class="p">,</span>   <span class="n">global</span> <span class="o">=</span> 
                <span class="p">{</span>   
                    <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_dir"</span><span class="p">,</span>      <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the xcode application directory"</span>   <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"mobileprovision"</span><span class="p">,</span><span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Provisioning Profile File"</span>     <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"codesign"</span><span class="p">,</span>       <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Indentity"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"entitlements"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Entitlements"</span>     <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>

</code></pre>
</div>

<p class="warning">
是在`platforms`目录相关平台的`xmake.lua`中编写，而不是在工程目录的`xmake.lua`中。
</p>

<h5 id="platform_end">platform_end</h5>

<h6 id="结束定义平台">结束定义平台</h6>

<p>这是一个可选api，显示离开选项作用域，用法和<a href="#target_end">target_end</a>类似。</p>

<h5 id="set_os">set_os</h5>

<h6 id="设置平台系统">设置平台系统</h6>

<p>设置目标平台的操作系统，例如：<code class="highlighter-rouge">ios</code>, <code class="highlighter-rouge">android</code>, <code class="highlighter-rouge">linux</code>, <code class="highlighter-rouge">windows</code> 等</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span>
    <span class="n">set_os</span><span class="p">(</span><span class="s2">"ios"</span><span class="p">)</span>
</code></pre>
</div>

<p>这个一般用于在自定义脚本和插件开发中，<a href="#core-platform-platform">core.platform.platform</a>模块中进行访问，获取当前平台的操作系统。</p>

<h5 id="set_menu">set_menu</h5>

<h6 id="设置平台菜单">设置平台菜单</h6>

<p>先给个设置的例子：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span>
    <span class="o">...</span>

    <span class="c1">-- 设置平台的帮助菜单</span>
    <span class="n">set_menu</span> <span class="p">{</span>
                <span class="n">config</span> <span class="o">=</span> 
                <span class="p">{</span>   
                    <span class="p">{}</span>   
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_dir"</span><span class="p">,</span>      <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the xcode application directory"</span>   <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_sdkver"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the sdk version for xcode"</span>         <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"target_minver"</span><span class="p">,</span>  <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the target minimal version"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"mobileprovision"</span><span class="p">,</span><span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Provisioning Profile File"</span>     <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"codesign"</span><span class="p">,</span>       <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Indentity"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"entitlements"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Entitlements"</span>     <span class="p">}</span>
                <span class="p">}</span>

            <span class="p">,</span>   <span class="n">global</span> <span class="o">=</span> 
                <span class="p">{</span>   
                    <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"xcode_dir"</span><span class="p">,</span>      <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"the xcode application directory"</span>   <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"mobileprovision"</span><span class="p">,</span><span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Provisioning Profile File"</span>     <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"codesign"</span><span class="p">,</span>       <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Indentity"</span>        <span class="p">}</span>
                <span class="p">,</span>   <span class="p">{</span><span class="kc">nil</span><span class="p">,</span> <span class="s2">"entitlements"</span><span class="p">,</span>   <span class="s2">"kv"</span><span class="p">,</span> <span class="s2">"auto"</span><span class="p">,</span>       <span class="s2">"The Code Signing Entitlements"</span>     <span class="p">}</span>
                <span class="p">}</span>
            <span class="p">}</span>
</code></pre>
</div>

<p>其中<code class="highlighter-rouge">config</code>组用来设置：<code class="highlighter-rouge">xmake f --help</code>中的本地工程菜单，<code class="highlighter-rouge">global</code>用来设置：<code class="highlighter-rouge">xmake g --help</code>全局平台配置中的菜单。</p>

<p>具体设置格式可参考：<a href="#taskset_menu">task:set_menu</a>。</p>

<h5 id="set_hosts">set_hosts</h5>

<h6 id="设置平台支持的主机环境">设置平台支持的主机环境</h6>

<p>用来设置当前目标平台支持主机构建环境，例如<code class="highlighter-rouge">iphoneos</code>平台可以在<code class="highlighter-rouge">macosx</code>主机系统上构建，那么可以设置为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span>
    <span class="n">set_hosts</span><span class="p">(</span><span class="s2">"macosx"</span><span class="p">)</span>
</code></pre>
</div>

<p>而<code class="highlighter-rouge">android</code>平台可以同时在<code class="highlighter-rouge">linux</code>, “macosx”, <code class="highlighter-rouge">windows</code>主机环境中构建，那么可以设置为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"android"</span><span class="p">)</span>
    <span class="n">set_hosts</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">,</span> <span class="s2">"macosx"</span><span class="p">,</span> <span class="s2">"windows"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="set_archs">set_archs</h5>

<h6 id="设置平台支持的架构环境">设置平台支持的架构环境</h6>

<p>用来设置当前目标平台支持的编译架构环境，例如<code class="highlighter-rouge">iphoneos</code>平台可以构建<code class="highlighter-rouge">armv7</code>, <code class="highlighter-rouge">armv7s</code>, <code class="highlighter-rouge">arm64</code>, <code class="highlighter-rouge">i386</code>, <code class="highlighter-rouge">x86_64</code>等架构，那么可以设置为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"iphoneos"</span><span class="p">)</span>
    <span class="n">set_archs</span><span class="p">(</span><span class="s2">"armv7"</span><span class="p">,</span> <span class="s2">"armv7s"</span><span class="p">,</span> <span class="s2">"arm64"</span><span class="p">,</span> <span class="s2">"i386"</span><span class="p">,</span> <span class="s2">"x86_64"</span><span class="p">)</span>
</code></pre>
</div>

<p>配置好架构后，执行：<code class="highlighter-rouge">xmake f -h</code>，就会在对应arch参数描述，自动显示设置的架构列表：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>    -a ARCH, --arch=ARCH                   Compile for the given architecture. (default: auto)
                                               - android: armv5te armv6 armv7-a armv8-a arm64-v8a
                                               - iphoneos: armv7 armv7s arm64 i386 x86_64
                                               - linux: i386 x86_64
                                               - macosx: i386 x86_64
                                               - mingw: i386 x86_64
                                               - watchos: armv7k i386
                                               - windows: x86 x64 amd64 x86_amd64
</code></pre>
</div>

<h5 id="set_tooldirs">set_tooldirs</h5>

<h6 id="设置平台工具的搜索目录">设置平台工具的搜索目录</h6>

<p>xmake会自动检测当前平台支持的一些构建工具是否存在，例如编译器、链接器等，如果要提高检测通过率，可以在平台配置的时候，设置一些工具环境搜索目录，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">)</span>

    <span class="c1">-- 在linux下检测这些目录环境</span>
    <span class="n">set_tooldirs</span><span class="p">(</span><span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">,</span> <span class="s2">"/opt/bin"</span><span class="p">,</span> <span class="s2">"/opt/local/bin"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="on_load">on_load</h5>

<h6 id="设置加载平台环境配置脚本">设置加载平台环境配置脚本</h6>

<p>一般用于在平台刚加载时，设置一些基本配置：生成目标文件命名格式、平台相关编译选项等</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"windows"</span><span class="p">)</span>

    <span class="c1">-- on load</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>

        <span class="c1">-- init the file formats</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span>          <span class="o">=</span> <span class="p">{}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span><span class="p">.</span><span class="n">static</span>   <span class="o">=</span> <span class="p">{</span><span class="s2">""</span><span class="p">,</span> <span class="s2">".lib"</span><span class="p">}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span><span class="p">.</span><span class="n">object</span>   <span class="o">=</span> <span class="p">{</span><span class="s2">""</span><span class="p">,</span> <span class="s2">".obj"</span><span class="p">}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span><span class="p">.</span><span class="n">shared</span>   <span class="o">=</span> <span class="p">{</span><span class="s2">""</span><span class="p">,</span> <span class="s2">".dll"</span><span class="p">}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span><span class="p">.</span><span class="n">binary</span>   <span class="o">=</span> <span class="p">{</span><span class="s2">""</span><span class="p">,</span> <span class="s2">".exe"</span><span class="p">}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">formats</span><span class="p">.</span><span class="n">symbol</span>   <span class="o">=</span> <span class="p">{</span><span class="s2">""</span><span class="p">,</span> <span class="s2">".pdb"</span><span class="p">}</span>

        <span class="c1">-- init flags for dlang</span>
        <span class="kd">local</span> <span class="n">dc_archs</span> <span class="o">=</span> <span class="p">{</span> <span class="n">x86</span> <span class="o">=</span> <span class="s2">"-m32"</span><span class="p">,</span> <span class="n">x64</span> <span class="o">=</span> <span class="s2">"-m64"</span><span class="p">,</span> <span class="n">amd64</span> <span class="o">=</span> <span class="s2">"-m64"</span><span class="p">,</span> <span class="n">x86_amd64</span> <span class="o">=</span> <span class="s2">"-m64"</span> <span class="p">}</span>
        <span class="n">_g</span><span class="p">.</span><span class="n">dcflags</span>       <span class="o">=</span> <span class="p">{</span> <span class="n">dc_archs</span><span class="p">[</span><span class="n">arch</span><span class="p">]</span> <span class="ow">or</span> <span class="s2">""</span> <span class="p">}</span>
        <span class="n">_g</span><span class="p">[</span><span class="s2">"dc-shflags"</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">dc_archs</span><span class="p">[</span><span class="n">arch</span><span class="p">]</span> <span class="ow">or</span> <span class="s2">""</span> <span class="p">}</span>
        <span class="n">_g</span><span class="p">[</span><span class="s2">"dc-ldflags"</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">dc_archs</span><span class="p">[</span><span class="n">arch</span><span class="p">]</span> <span class="ow">or</span> <span class="s2">""</span> <span class="p">}</span>

        <span class="c1">-- ok</span>
        <span class="k">return</span> <span class="n">_g</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>如果加载逻辑比较复杂，可以独立成单独<code class="highlighter-rouge">init.lua</code>文件，然后设置为：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"xxxx"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="s2">"init"</span><span class="p">)</span>
</code></pre>
</div>

<p>通过这种方式，会自动加载平台脚本目录下对应的<code class="highlighter-rouge">init.lua</code>文件，调用<code class="highlighter-rouge">function main() end</code>函数入口，完成复杂加载逻辑。</p>

<h5 id="on_check">on_check</h5>

<h6 id="设置平台工具的检测脚本">设置平台工具的检测脚本</h6>

<p>由于每个平台检测的工具非常多，脚本比较复杂，一般直接独立成<code class="highlighter-rouge">check.lua</code>文件来实现检测逻辑，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">platform</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">)</span>
    <span class="n">on_check</span><span class="p">(</span><span class="s2">"check"</span><span class="p">)</span>
</code></pre>
</div>

<p>具体的检测代码入口如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- check it</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="n">kind</span><span class="p">)</span>

    <span class="c1">-- init the check list of config</span>
    <span class="n">_g</span><span class="p">.</span><span class="n">config</span> <span class="o">=</span> 
    <span class="p">{</span>
        <span class="n">__check_arch</span>
    <span class="p">,</span>   <span class="n">checker</span><span class="p">.</span><span class="n">check_ccache</span>
    <span class="p">,</span>   <span class="n">_check_toolchains</span>
    <span class="p">}</span>

    <span class="c1">-- init the check list of global</span>
    <span class="n">_g</span><span class="p">.</span><span class="n">global</span> <span class="o">=</span> 
    <span class="p">{</span>
        <span class="n">checker</span><span class="p">.</span><span class="n">check_ccache</span>
    <span class="p">,</span>   <span class="n">_check_ndk_sdkver</span>
    <span class="p">}</span>

    <span class="c1">-- check it</span>
    <span class="n">checker</span><span class="p">.</span><span class="n">check</span><span class="p">(</span><span class="n">kind</span><span class="p">,</span> <span class="n">_g</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>具体实现这里就不介绍了，可以参考xmake源码目录下的<code class="highlighter-rouge">platforms</code>平台配置代码: <a href="https://github.com/xmake-io/xmake/blob/master/xmake/platforms/macosx/check.lua">check.lua</a></p>

<h5 id="on_install">on_install</h5>

<h6 id="设置目标工程在指定平台的安装脚本">设置目标工程在指定平台的安装脚本</h6>

<p>具体实现逻辑见xmake源码：<a href="https://github.com/xmake-io/xmake/blob/master/xmake/platforms/macosx/install.lua">install.lua</a></p>

<h5 id="on_uninstall">on_uninstall</h5>

<h6 id="设置目标工程在指定平台的卸载脚本">设置目标工程在指定平台的卸载脚本</h6>

<p>具体实现逻辑见xmake源码：<a href="https://github.com/xmake-io/xmake/blob/master/xmake/platforms/macosx/uninstall.lua">uninstall.lua</a></p>

<h4 id="extension-languages">Extension Languages</h4>

<p>有待后续完善。。</p>

<h4 id="project-templates">Project Templates</h4>

<h5 id="template">template</h5>
<h5 id="set_description">set_description</h5>
<h5 id="set_projectdir">set_projectdir</h5>
<h5 id="add_macros">add_macros</h5>
<h5 id="add_macrofiles">add_macrofiles</h5>

<h4 id="builtin-variables">Builtin Variables</h4>

<p>xmake提供了 <code class="highlighter-rouge">$(varname)</code> 的语法，来支持内置变量的获取，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_cxflags</span><span class="p">(</span><span class="s2">"-I$(buildir)"</span><span class="p">)</span>
</code></pre>
</div>

<p>它将会在在实际编译的时候，将内置的 <code class="highlighter-rouge">buildir</code> 变量转换为实际的构建输出目录：<code class="highlighter-rouge">-I./build</code></p>

<p>一般内置变量可用于在传参时快速获取和拼接变量字符串，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 添加工程源码目录下的源文件</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"$(projectdir)/src/*.c"</span><span class="p">)</span>

    <span class="c1">-- 添加构建目录下的头文件搜索路径</span>
    <span class="n">add_includedirs</span><span class="p">(</span><span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
</code></pre>
</div>

<p>也可以在自定义脚本的模块接口中使用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="c1">-- 复制当前脚本目录下的头文件到输出目录</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"$(scriptdir)/xxx.h"</span><span class="p">,</span> <span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>所有的内置变量，也可以通过<a href="#val">val</a>接口，来获取他们的值。</p>

<p>这种使用内置变量的方式，使得描述编写更加的简洁易读，下面是一些xmake内置的变量，可以直接获取：</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#var-os">$(os)</a></td>
      <td>获取当前编译平台的操作系统</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-host">$(host)</a></td>
      <td>获取本机操作系统</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-tmpdir">$(tmpdir)</a></td>
      <td>获取临时目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-curdir">$(curdir)</a></td>
      <td>获取当前目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-buildir">$(buildir)</a></td>
      <td>获取构建输出目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-scriptdir">$(scriptdir)</a></td>
      <td>获取工程描述脚本目录</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#var-globaldir">$(globaldir)</a></td>
      <td>获取全局配置目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-configdir">$(configdir)</a></td>
      <td>获取本地工程配置目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-programdir">$(programdir)</a></td>
      <td>xmake安装脚本目录</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#var-projectdir">$(projectdir)</a></td>
      <td>获取工程根目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-shell">$(shell)</a></td>
      <td>执行外部shell命令</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#var-env">$(env)</a></td>
      <td>获取外部环境变量</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#var-reg">$(reg)</a></td>
      <td>获取windows注册表配置项的值</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<p>当然这种变量模式，也是可以扩展的，默认通过<code class="highlighter-rouge">xmake f --var=val</code>命令，配置的参数都是可以直接获取，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"-DTEST=$(var)"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
所有`xmake f --xxx=...`配置的参数值，都是可以通过内置变量获取到，例如：`xmake f --arch=x86`对应`$(arch)`，其他的还有`$(plat)`, `$(mode)`等等。
具体有哪些参数，可以通过：`xmake f -h`才查看。
</p>

<p>既然支持直接从配置选项中获取，那么当然也就能很方便的扩展自定义的选项，来获取自定义的变量了，具体如何自定义选项见：<a href="#option">option</a></p>

<h5 id="varos">var.$(os)</h5>

<h6 id="获取当前编译平台的操作系统">获取当前编译平台的操作系统</h6>

<p>如果当前编译的是iphoneos，那么这个值就是：<code class="highlighter-rouge">ios</code>，以此类推。</p>

<h5 id="varhost">var.$(host)</h5>

<h6 id="获取本机操作系统">获取本机操作系统</h6>

<p>指的是当前本机环境的主机系统，如果你是在macOS上编译，那么系统就是：<code class="highlighter-rouge">macosx</code></p>

<h5 id="vartmpdir">var.$(tmpdir)</h5>

<h6 id="获取临时目录">获取临时目录</h6>

<p>一般用于临时存放一些非永久性文件。</p>

<h5 id="varcurdir">var.$(curdir)</h5>

<h6 id="获取当前目录">获取当前目录</h6>

<p>一般默认是执行<code class="highlighter-rouge">xmake</code>命令时的工程根目录，当然如果通过<a href="#os-cd">os.cd</a>改变了目录的话，这个值也会一起改变。</p>

<h5 id="varbuildir">var.$(buildir)</h5>

<h6 id="获取当前的构建输出目录">获取当前的构建输出目录</h6>

<p>默认一般为当前工程根目录下的：<code class="highlighter-rouge">./build</code>目录，也可以通过执行：<code class="highlighter-rouge">xmake f -o /tmp/build</code>命令来修改默认的输出目录。</p>

<h5 id="varscriptdir">var.$(scriptdir)</h5>

<h6 id="获取当前工程描述脚本的目录">获取当前工程描述脚本的目录</h6>

<p>也就是对应<code class="highlighter-rouge">xmake.lua</code>所在的目录路径。</p>

<h5 id="varglobaldir">var.$(globaldir)</h5>

<h6 id="全局配置目录">全局配置目录</h6>

<p>xmake的<code class="highlighter-rouge">xmake g|global</code>全局配置命令，数据存储的目录路径，在里面可以放置一些自己的插件、平台脚本。</p>

<p>默认为：<code class="highlighter-rouge">~/.config</code></p>

<h5 id="varconfigdir">var.$(configdir)</h5>

<h6 id="当前工程配置目录">当前工程配置目录</h6>

<p>当前工程的配置存储目录，也就是<code class="highlighter-rouge">xmake f|config</code>配置命令的存储目录，默认为：<code class="highlighter-rouge">projectdir/.config</code></p>

<h5 id="varprogramdir">var.$(programdir)</h5>

<h6 id="xmake安装脚本目录">xmake安装脚本目录</h6>

<p>也就是<code class="highlighter-rouge">XMAKE_PROGRAM_DIR</code>环境变量所在目录，我们也可以通过设置这个环境量，来修改xmake的加载脚本，实现版本切换。</p>

<h5 id="varprojectdir">var.$(projectdir)</h5>

<h6 id="工程根目录">工程根目录</h6>

<p>也就是<code class="highlighter-rouge">xmake -P xxx</code>命令中指定的目录路径，默认不指定就是<code class="highlighter-rouge">xmake</code>命令执行时的当前目录，一般用于定位工程文件。</p>

<h5 id="varshell">var.$(shell)</h5>

<h6 id="执行外部shell命令">执行外部shell命令</h6>

<p>除了内置的变量处理，xmake还支持原生shell的运行，来处理一些xmake内置不支持的功能</p>

<p>例如，现在有个需求，我想用在编译linux程序时，调用<code class="highlighter-rouge">pkg-config</code>获取到实际的第三方链接库名，可以这么做：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">)</span> <span class="k">then</span>
        <span class="n">add_ldflags</span><span class="p">(</span><span class="s2">"$(shell pkg-config --libs sqlite3)"</span><span class="p">)</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>当然，xmake有自己的自动化第三库检测机制，一般情况下不需要这么麻烦，而且lua自身的脚本化已经很不错了。。</p>

<p>但是这个例子可以说明，xmake是完全可以通过原生shell，来与一些第三方的工具进行配合使用。。</p>

<h5 id="varenv">var.$(env)</h5>

<h6 id="获取外部环境变量">获取外部环境变量</h6>

<p>例如，可以通过获取环境变量中的路径：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">add_includedirs</span><span class="p">(</span><span class="s2">"$(env PROGRAMFILES)/OpenSSL/inc"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="varreg">var.$(reg)</h5>

<h6 id="获取windows注册表配置项的值">获取windows注册表配置项的值</h6>

<p>通过 <code class="highlighter-rouge">regpath; name</code> 的方式获取注册表中某个项的值：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="s2">"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"</span><span class="p">)</span>
</code></pre>
</div>

<h4 id="builtin-modules">Builtin Modules</h4>

<p>在自定义脚本、插件脚本、任务脚本、平台扩展、模板扩展等脚本代码中使用，也就是在类似下面的代码块中，可以使用这些模块接口：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
<span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
为了保证外层的描述域尽可能简洁、安全，一般不建议在这个域使用接口和模块操作api，因此大部分模块接口只能在脚本域使用，来实现复杂功能。&lt;/br&gt;
当然少部分只读的内置接口还是可以在描述域使用的，具体见下表：
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>可使用域</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#val">val</a></td>
      <td>获取内置变量的值</td>
      <td>脚本域</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#import">import</a></td>
      <td>导入扩展摸块</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#inherit">inherit</a></td>
      <td>导入并继承基类模块</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#ifelse">ifelse</a></td>
      <td>类似三元条件判断</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#try-catch-finally">try-catch-finally</a></td>
      <td>异常捕获</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#pairs">pairs</a></td>
      <td>用于遍历字典</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#ipairs">ipairs</a></td>
      <td>用于遍历数组</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#print">print</a></td>
      <td>换行打印终端日志</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#printf">printf</a></td>
      <td>无换行打印终端日志</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#cprint">cprint</a></td>
      <td>换行彩色打印终端日志</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#cprintf">cprintf</a></td>
      <td>无换行彩色打印终端日志</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#format">format</a></td>
      <td>格式化字符串</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#vformat">vformat</a></td>
      <td>格式化字符串，支持内置变量转义</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#raise">raise</a></td>
      <td>抛出异常中断程序</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os">os</a></td>
      <td>系统操作模块</td>
      <td>部分只读操作描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io">io</a></td>
      <td>文件操作模块</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path">path</a></td>
      <td>路径操作模块</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#table">table</a></td>
      <td>数组和字典操作模块</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#string">string</a></td>
      <td>字符串操作模块</td>
      <td>描述域、脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#process">process</a></td>
      <td>进程操作模块</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#coroutine">coroutine</a></td>
      <td>协程操作模块</td>
      <td>脚本域</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<p>在描述域使用接口调用的实例如下，一般仅用于条件控制：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 扫描当前xmake.lua目录下的所有子目录，以每个目录的名字定义一个task任务</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">taskname</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">dirs</span><span class="p">(</span><span class="s2">"*"</span><span class="p">),</span> <span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">)</span> <span class="k">do</span>
    <span class="n">task</span><span class="p">(</span><span class="n">taskname</span><span class="p">)</span>
        <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>
        <span class="k">end</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>上面所说的脚本域、描述域主要是指：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 描述域</span>
<span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    
    <span class="c1">-- 描述域</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"static"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>

    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="c1">-- 脚本域</span>
    <span class="k">end</span><span class="p">)</span>

<span class="c1">-- 描述域</span>
</code></pre>
</div>

<h5 id="val">val</h5>

<h6 id="获取内置变量的值">获取内置变量的值</h6>

<p><a href="#内置变量">内置变量</a>可以通过此接口直接获取，而不需要再加<code class="highlighter-rouge">$()</code>的包裹，使用更加简单，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">val</span><span class="p">(</span><span class="s2">"host"</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">val</span><span class="p">(</span><span class="s2">"env PATH"</span><span class="p">))</span>
<span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="n">val</span><span class="p">(</span><span class="s2">"shell echo hello"</span><span class="p">)</span>
</code></pre>
</div>

<p>而用<a href="#vformat">vformat</a>就比较繁琐了：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="n">vformat</span><span class="p">(</span><span class="s2">"$(shell echo hello)"</span><span class="p">)</span>
</code></pre>
</div>

<p>不过<code class="highlighter-rouge">vformat</code>支持字符串参数格式化，更加强大， 所以应用场景不同。</p>

<h5 id="import">import</h5>

<h6 id="导入扩展摸块">导入扩展摸块</h6>

<p>import的主要用于导入xmake的扩展类库以及一些自定义的类库模块，一般用于：</p>

<ul>
  <li>自定义脚本(<a href="#targeton_build">on_build</a>, <a href="#targeton_run">on_run</a> ..)</li>
  <li>插件开发</li>
  <li>模板开发</li>
  <li>平台扩展</li>
  <li>自定义任务task</li>
</ul>

<p>导入机制如下：</p>

<ol>
  <li>优先从当前脚本目录下导入</li>
  <li>再从扩展类库中导入</li>
</ol>

<p>导入的语法规则：</p>

<p>基于<code class="highlighter-rouge">.</code>的类库路径规则，例如：</p>

<p>导入core核心扩展模块</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.project"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span> <span class="c1">-- 2.1.5 以前是 core.project.task</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">()</span>
    
    <span class="c1">-- 获取参数选项</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">))</span>

    <span class="c1">-- 运行任务和插件</span>
    <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">project</span><span class="p">.</span><span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">core</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>导入当前目录下的自定义模块：</p>

<p>目录结构：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>plugin
  - xmake.lua
  - main.lua
  - modules
    - hello1.lua
    - hello2.lua
</code></pre>
</div>

<p>在main.lua中导入modules</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"modules.hello1"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"modules.hello2"</span><span class="p">)</span>
</code></pre>
</div>

<p>导入后就可以直接使用里面的所有公有接口，私有接口用<code class="highlighter-rouge">_</code>前缀标示，表明不会被导出，不会被外部调用到。。</p>

<p>除了当前目录，我们还可以导入其他指定目录里面的类库，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"hello3"</span><span class="p">,</span> <span class="p">{</span><span class="n">rootdir</span> <span class="o">=</span> <span class="s2">"/home/xxx/modules"</span><span class="p">})</span>
</code></pre>
</div>

<p>为了防止命名冲突，导入后还可以指定的别名：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.platform.platform"</span><span class="p">,</span> <span class="p">{</span><span class="n">alias</span> <span class="o">=</span> <span class="s2">"p"</span><span class="p">})</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">()</span>
 
    <span class="c1">-- 这样我们就可以使用p来调用platform模块的plats接口，获取所有xmake支持的平台列表了</span>
    <span class="n">table</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">plats</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<p>import不仅可以导入类库，还支持导入的同时作为继承导入，实现模块间的继承关系</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"xxx.xxx"</span><span class="p">,</span> <span class="p">{</span><span class="n">inherit</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<p>这样导入的不是这个模块的引用，而是导入的这个模块的所有公有接口本身，这样就会跟当前模块的接口进行合并，实现模块间的继承。</p>

<p>2.1.5版本新增两个新属性：<code class="highlighter-rouge">import("xxx.xxx", {try = true, anonymous = true})</code></p>

<p>try为true，则导入的模块不存在的话，仅仅返回nil，并不会抛异常后中断xmake.
anonymous为true，则导入的模块不会引入当前作用域，仅仅在import接口返回导入的对象引用。</p>

<h5 id="inherit">inherit</h5>

<h6 id="导入并继承基类模块">导入并继承基类模块</h6>

<p>这个等价于<a href="#import">import</a>接口的<code class="highlighter-rouge">inherit</code>模式，也就是：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"xxx.xxx"</span><span class="p">,</span> <span class="p">{</span><span class="n">inherit</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<p>用<code class="highlighter-rouge">inherit</code>接口的话，会更简洁些：</p>

<pre><code class="language-lu">inherit("xxx.xxx")
</code></pre>

<p>使用实例，可以参看xmake的tools目录下的脚本：<a href="#https://github.com/xmake-io/xmake/blob/master/xmake/tools/clang.lua">clang.lua</a></p>

<p>这个就是clang工具模块继承了gcc的部分实现。</p>

<h5 id="ifelse">ifelse</h5>

<h6 id="类似三元条件判断">类似三元条件判断</h6>

<p>由于lua没有内置的三元运算符，通过封装<code class="highlighter-rouge">ifelse</code>接口，实现更加简洁的条件选择：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">ifelse</span><span class="p">(</span><span class="n">a</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"ok"</span><span class="p">,</span> <span class="s2">"no"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="try-catch-finally">try-catch-finally</h5>

<h6 id="异常捕获">异常捕获</h6>

<p>lua原生并没有提供try-catch的语法来捕获异常处理，但是提供了<code class="highlighter-rouge">pcall/xpcall</code>等接口，可在保护模式下执行lua函数。</p>

<p>因此，可以通过封装这两个接口，来实现try-catch块的捕获机制。</p>

<p>我们可以先来看下，封装后的try-catch使用方式：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">try</span>
<span class="p">{</span>
    <span class="c1">-- try 代码块</span>
    <span class="k">function</span> <span class="p">()</span>
        <span class="nb">error</span><span class="p">(</span><span class="s2">"error message"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">,</span>

    <span class="c1">-- catch 代码块</span>
    <span class="n">catch</span> 
    <span class="p">{</span>
        <span class="c1">-- 发生异常后，被执行</span>
        <span class="k">function</span> <span class="p">(</span><span class="n">errors</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<p>上面的代码中，在try块内部认为引发了一个异常，并且抛出错误消息，在catch中进行了捕获，并且将错误消息进行输出显示。</p>

<p>而finally的处理，这个的作用是对于<code class="highlighter-rouge">try{}</code>代码块，不管是否执行成功，都会执行到finally块中</p>

<p>也就说，其实上面的实现，完整的支持语法是：<code class="highlighter-rouge">try-catch-finally</code>模式，其中catch和finally都是可选的，根据自己的实际需求提供</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">try</span>
<span class="p">{</span>
    <span class="c1">-- try 代码块</span>
    <span class="k">function</span> <span class="p">()</span>
        <span class="nb">error</span><span class="p">(</span><span class="s2">"error message"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">,</span>

    <span class="c1">-- catch 代码块</span>
    <span class="n">catch</span> 
    <span class="p">{</span>
        <span class="c1">-- 发生异常后，被执行</span>
        <span class="k">function</span> <span class="p">(</span><span class="n">errors</span><span class="p">)</span>
            <span class="nb">print</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="p">},</span>

    <span class="c1">-- finally 代码块</span>
    <span class="n">finally</span> 
    <span class="p">{</span>
        <span class="c1">-- 最后都会执行到这里</span>
        <span class="k">function</span> <span class="p">(</span><span class="n">ok</span><span class="p">,</span> <span class="n">errors</span><span class="p">)</span>
            <span class="c1">-- 如果try{}中存在异常，ok为true，errors为错误信息，否则为false，errors为try中的返回值</span>
        <span class="k">end</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre>
</div>

<p>或者只有finally块：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">try</span>
<span class="p">{</span>
    <span class="c1">-- try 代码块</span>
    <span class="k">function</span> <span class="p">()</span>
        <span class="k">return</span> <span class="s2">"info"</span>
    <span class="k">end</span><span class="p">,</span>

    <span class="c1">-- finally 代码块</span>
    <span class="n">finally</span> 
    <span class="p">{</span>
        <span class="c1">-- 由于此try代码没发生异常，因此ok为true，errors为返回值: "info"</span>
        <span class="k">function</span> <span class="p">(</span><span class="n">ok</span><span class="p">,</span> <span class="n">errors</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<p>处理可以在finally中获取try里面的正常返回值，其实在仅有try的情况下，也是可以获取返回值的：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 如果没发生异常，result 为返回值："xxxx"，否则为nil</span>
<span class="kd">local</span> <span class="n">result</span> <span class="o">=</span> <span class="n">try</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="p">()</span>
        <span class="k">return</span> <span class="s2">"xxxx"</span>
    <span class="k">end</span>
<span class="p">}</span>
</code></pre>
</div>

<p>在xmake的自定义脚本、插件开发中，也是完全基于此异常捕获机制</p>

<p>这样使得扩展脚本的开发非常的精简可读，省去了繁琐的<code class="highlighter-rouge">if err ~= nil then</code>返回值判断，在发生错误时，xmake会直接抛出异常进行中断，然后高亮提示详细的错误信息。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>

    <span class="c1">-- 在编译完ios程序后，对目标程序进行ldid签名</span>
    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">))</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ldid -S %s"</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>只需要一行<code class="highlighter-rouge">os.run</code>就行了，也不需要返回值判断是否运行成功，因为运行失败后，xmake会自动抛异常，中断程序并且提示错误</p>

<p>如果你想在运行失败后，不直接中断xmake，继续往下运行，可以自己加个try快就行了：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>

    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">))</span>
        <span class="n">try</span>
        <span class="p">{</span>
            <span class="k">function</span> <span class="p">()</span>
                <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ldid -S %s"</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
            <span class="k">end</span>
        <span class="p">}</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>如果还想捕获出错信息，可以再加个catch:</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>

    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">))</span>
        <span class="n">try</span>
        <span class="p">{</span>
            <span class="k">function</span> <span class="p">()</span>
                <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ldid -S %s"</span><span class="p">,</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
            <span class="k">end</span><span class="p">,</span>
            <span class="n">catch</span> 
            <span class="p">{</span>
                <span class="k">function</span> <span class="p">(</span><span class="n">errors</span><span class="p">)</span>
                    <span class="nb">print</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
                <span class="k">end</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>不过一般情况下，在xmake中写自定义脚本，是不需要手动加try-catch的，直接调用各种api，出错后让xmake默认的处理程序接管，直接中断就行了。。</p>

<h5 id="pairs">pairs</h5>

<h6 id="用于遍历字典">用于遍历字典</h6>

<p>这个是lua原生的内置api，在xmake中，在原有的行为上对其进行了一些扩展，来简化一些日常的lua遍历代码。</p>

<p>先看下默认的原生写法：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">t</span> <span class="o">=</span> <span class="p">{</span><span class="n">a</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s2">"b"</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s2">"c"</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="s2">"d"</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="s2">"e"</span><span class="p">,</span> <span class="n">f</span> <span class="o">=</span> <span class="s2">"f"</span><span class="p">}</span>

<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">t</span><span class="p">)</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"%s: %s"</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>这对于通常的遍历操作就足够了，但是如果我们相对其中每个遍历出来的元素，获取其大写，我们可以这么写：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">return</span> <span class="n">v</span><span class="p">:</span><span class="n">upper</span><span class="p">()</span> <span class="k">end</span><span class="p">)</span> <span class="k">do</span>
     <span class="nb">print</span><span class="p">(</span><span class="s2">"%s: %s"</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>甚至传入一些参数到第二个<code class="highlighter-rouge">function</code>中，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="k">return</span> <span class="n">v</span><span class="p">:</span><span class="n">upper</span><span class="p">()</span> <span class="o">..</span> <span class="n">a</span> <span class="o">..</span> <span class="n">b</span> <span class="k">end</span><span class="p">,</span> <span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">)</span> <span class="k">do</span>
     <span class="nb">print</span><span class="p">(</span><span class="s2">"%s: %s"</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="ipairs">ipairs</h5>

<h6 id="用于遍历数组">用于遍历数组</h6>

<p>这个是lua原生的内置api，在xmake中，在原有的行为上对其进行了一些扩展，来简化一些日常的lua遍历代码。</p>

<p>先看下默认的原生写法：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span> <span class="s2">"f"</span><span class="p">})</span> <span class="k">do</span>
     <span class="nb">print</span><span class="p">(</span><span class="s2">"%d %s"</span><span class="p">,</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>扩展写法类似<a href="#pairs">pairs</a>接口，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span> <span class="s2">"f"</span><span class="p">},</span> <span class="k">function</span> <span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="k">return</span> <span class="n">v</span><span class="p">:</span><span class="n">upper</span><span class="p">()</span> <span class="k">end</span><span class="p">)</span> <span class="k">do</span>
     <span class="nb">print</span><span class="p">(</span><span class="s2">"%d %s"</span><span class="p">,</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>

<span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span> <span class="s2">"f"</span><span class="p">},</span> <span class="k">function</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="k">return</span> <span class="n">v</span><span class="p">:</span><span class="n">upper</span><span class="p">()</span> <span class="o">..</span> <span class="n">a</span> <span class="o">..</span> <span class="n">b</span> <span class="k">end</span><span class="p">,</span> <span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">)</span> <span class="k">do</span>
     <span class="nb">print</span><span class="p">(</span><span class="s2">"%d %s"</span><span class="p">,</span> <span class="n">idx</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>这样可以简化<code class="highlighter-rouge">for</code>块代码的逻辑，例如我要遍历指定目录，获取其中的文件名，但不包括路径，就可以通过这种扩展方式，简化写法：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">filename</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">dirs</span><span class="p">(</span><span class="s2">"*"</span><span class="p">),</span> <span class="n">path</span><span class="p">.</span><span class="n">filename</span><span class="p">)</span> <span class="k">do</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="print">print</h5>

<h6 id="换行打印终端日志">换行打印终端日志</h6>

<p>此接口也是lua的原生接口，xmake在原有行为不变的基础上也进行了扩展，同时支持：格式化输出、多变量输出。</p>

<p>先看下原生支持的方式：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">,</span> <span class="mi">123</span><span class="p">)</span>
</code></pre>
</div>

<p>并且同时还支持扩展的格式化写法：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="s2">"hello %s!"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake! %d"</span><span class="p">,</span> <span class="mi">123</span><span class="p">)</span>
</code></pre>
</div>

<p>xmake会同时支持这两种写法，内部会去自动智能检测，选择输出行为。</p>

<h5 id="printf">printf</h5>

<h6 id="无换行打印终端日志">无换行打印终端日志</h6>

<p>类似<a href="#print">print</a>接口，唯一的区别就是不换行。</p>

<h5 id="cprint">cprint</h5>

<h6 id="换行彩色打印终端日志">换行彩色打印终端日志</h6>

<p>行为类似<a href="#print">print</a>，区别就是此接口还支持彩色终端输出，并且支持<code class="highlighter-rouge">emoji</code>字符输出。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${bright}hello xmake'</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${red}hello xmake'</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${bright green}hello ${clear}xmake'</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${blue onyellow underline}hello xmake${clear}'</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${red}hello ${magenta}xmake'</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s1">'${cyan}hello ${dim yellow}xmake'</span><span class="p">)</span>
</code></pre>
</div>

<p>显示结果如下：</p>

<p><img src="https://tboox.org/static/img/xmake/cprint_colors.png" alt="cprint_colors" /></p>

<p>跟颜色相关的描述，都放置在 <code class="highlighter-rouge">${  }</code> 里面，可以同时设置多个不同的属性，例如：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>    ${bright red underline onyellow}
</code></pre>
</div>

<p>表示：高亮红色，背景黄色，并且带下滑线</p>

<p>所有这些描述，都会影响后面一整行字符，如果只想显示部分颜色的文字，可以在结束位置，插入<code class="highlighter-rouge">${clear}</code>清楚前面颜色描述</p>

<p>例如：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>    ${red}hello ${clear}xmake
</code></pre>
</div>

<p>这样的话，仅仅hello是显示红色，其他还是正常默认黑色显示。</p>

<p>其他颜色属于，我这里就不一一介绍，直接贴上xmake代码里面的属性列表吧：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>    <span class="n">colors</span><span class="p">.</span><span class="n">keys</span> <span class="o">=</span> 
    <span class="p">{</span>
        <span class="c1">-- 属性</span>
        <span class="n">reset</span>       <span class="o">=</span> <span class="mi">0</span> <span class="c1">-- 重置属性</span>
    <span class="p">,</span>   <span class="n">clear</span>       <span class="o">=</span> <span class="mi">0</span> <span class="c1">-- 清楚属性</span>
    <span class="p">,</span>   <span class="n">default</span>     <span class="o">=</span> <span class="mi">0</span> <span class="c1">-- 默认属性</span>
    <span class="p">,</span>   <span class="n">bright</span>      <span class="o">=</span> <span class="mi">1</span> <span class="c1">-- 高亮</span>
    <span class="p">,</span>   <span class="n">dim</span>         <span class="o">=</span> <span class="mi">2</span> <span class="c1">-- 暗色</span>
    <span class="p">,</span>   <span class="n">underline</span>   <span class="o">=</span> <span class="mi">4</span> <span class="c1">-- 下划线</span>
    <span class="p">,</span>   <span class="n">blink</span>       <span class="o">=</span> <span class="mi">5</span> <span class="c1">-- 闪烁</span>
    <span class="p">,</span>   <span class="n">reverse</span>     <span class="o">=</span> <span class="mi">7</span> <span class="c1">-- 反转颜色</span>
    <span class="p">,</span>   <span class="n">hidden</span>      <span class="o">=</span> <span class="mi">8</span> <span class="c1">-- 隐藏文字</span>

        <span class="c1">-- 前景色 </span>
    <span class="p">,</span>   <span class="n">black</span>       <span class="o">=</span> <span class="mi">30</span>
    <span class="p">,</span>   <span class="n">red</span>         <span class="o">=</span> <span class="mi">31</span>
    <span class="p">,</span>   <span class="n">green</span>       <span class="o">=</span> <span class="mi">32</span>
    <span class="p">,</span>   <span class="n">yellow</span>      <span class="o">=</span> <span class="mi">33</span>
    <span class="p">,</span>   <span class="n">blue</span>        <span class="o">=</span> <span class="mi">34</span>
    <span class="p">,</span>   <span class="n">magenta</span>     <span class="o">=</span> <span class="mi">35</span> 
    <span class="p">,</span>   <span class="n">cyan</span>        <span class="o">=</span> <span class="mi">36</span>
    <span class="p">,</span>   <span class="n">white</span>       <span class="o">=</span> <span class="mi">37</span>

        <span class="c1">-- 背景色 </span>
    <span class="p">,</span>   <span class="n">onblack</span>     <span class="o">=</span> <span class="mi">40</span>
    <span class="p">,</span>   <span class="n">onred</span>       <span class="o">=</span> <span class="mi">41</span>
    <span class="p">,</span>   <span class="n">ongreen</span>     <span class="o">=</span> <span class="mi">42</span>
    <span class="p">,</span>   <span class="n">onyellow</span>    <span class="o">=</span> <span class="mi">43</span>
    <span class="p">,</span>   <span class="n">onblue</span>      <span class="o">=</span> <span class="mi">44</span>
    <span class="p">,</span>   <span class="n">onmagenta</span>   <span class="o">=</span> <span class="mi">45</span>
    <span class="p">,</span>   <span class="n">oncyan</span>      <span class="o">=</span> <span class="mi">46</span>
    <span class="p">,</span>   <span class="n">onwhite</span>     <span class="o">=</span> <span class="mi">47</span>
</code></pre>
</div>

<p>除了可以色彩高亮显示外，如果你的终端是在macosx下，lion以上的系统，xmake还可以支持emoji表情的显示哦，对于不支持系统，会
忽略显示，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>    <span class="n">cprint</span><span class="p">(</span><span class="s2">"hello xmake${beer}"</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s2">"hello${ok_hand} xmake"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面两行代码，我打印了一个homebrew里面经典的啤酒符号，下面那行打印了一个ok的手势符号，是不是很炫哈。。</p>

<p><img src="https://tboox.org/static/img/xmake/cprint_emoji.png" alt="cprint_emoji" /></p>

<p>所有的emoji表情，以及xmake里面对应的key，都可以通过<a href="http://www.emoji-cheat-sheet.com/">emoji符号</a>里面找到。。</p>

<p>2.1.7版本支持24位真彩色输出，如果终端支持的话：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.base.colors"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">colors</span><span class="p">.</span><span class="n">truecolor</span><span class="p">()</span> <span class="k">then</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s2">"${255;0;0}hello"</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s2">"${on;255;0;0}hello${clear} xmake"</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s2">"${bright 255;0;0 underline}hello"</span><span class="p">)</span>
    <span class="n">cprint</span><span class="p">(</span><span class="s2">"${bright on;255;0;0 0;255;0}hello${clear} xmake"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>xmake对于truecolor的检测支持，是通过<code class="highlighter-rouge">$COLORTERM</code>环境变量来实现的，如果你的终端支持truecolor，可以手动设置此环境变量，来告诉xmake启用truecolor支持。</p>

<p>可以通过下面的命令来启用和测试：</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span><span class="nb">export </span><span class="nv">COLORTERM</span><span class="o">=</span>truecolor
<span class="gp">$ </span>xmake --version
</code></pre>
</div>

<p>2.1.7版本可通过<code class="highlighter-rouge">COLORTERM=nocolor</code>来禁用色彩输出。</p>

<h5 id="cprintf">cprintf</h5>

<h6 id="无换行彩色打印终端日志">无换行彩色打印终端日志</h6>

<p>此接口类似<a href="#cprint">cprint</a>，区别就是不换行输出。</p>

<h5 id="format">format</h5>

<h6 id="格式化字符串">格式化字符串</h6>

<p>如果只是想格式化字符串，不进行输出，可以使用这个接口，此接口跟<a href="#string-format">string.format</a>接口等价，只是个接口名简化版。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="n">format</span><span class="p">(</span><span class="s2">"hello %s"</span><span class="p">,</span> <span class="n">xmake</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="vformat">vformat</h5>

<h6 id="格式化字符串支持内置变量转义">格式化字符串，支持内置变量转义</h6>

<p>此接口跟<a href="#format">format</a>接口类似，只是增加对内置变量的获取和转义支持。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="n">vformat</span><span class="p">(</span><span class="s2">"hello %s $(mode) $(arch) $(env PATH)"</span><span class="p">,</span> <span class="n">xmake</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="raise">raise</h5>

<h6 id="抛出异常中断程序">抛出异常中断程序</h6>

<p>如果想在自定义脚本、插件任务中中断xmake运行，可以使用这个接口抛出异常，如果上层没有显示调用<a href="#try-catch-finally">try-catch</a>捕获的话，xmake就会中断执行，并且显示出错信息。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="p">(</span><span class="n">errors</span><span class="p">)</span> <span class="n">raise</span><span class="p">(</span><span class="n">errors</span><span class="p">)</span>
</code></pre>
</div>

<p>如果在try块中抛出异常，就会在catch和finally中进行errors信息捕获，具体见：<a href="#try-catch-finally">try-catch</a></p>

<h5 id="os">os</h5>

<p>系统操作模块，属于内置模块，无需使用<a href="#import">import</a>导入，可直接脚本域调用其接口。</p>

<p>此模块也是lua的原生模块，xmake在其基础上进行了扩展，提供更多实用的接口。</p>

<p class="tips">
os模块里面只有部分readonly接口（例如：`os.getenv`, `os.arch`）是可以在描述域中使用，其他接口只能在脚本域中使用，例如：`os.cp`, `os.rm`等
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#os-cp">os.cp</a></td>
      <td>复制文件或目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-mv">os.mv</a></td>
      <td>移动重命名文件或目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-rm">os.rm</a></td>
      <td>删除文件或目录树</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-trycp">os.trycp</a></td>
      <td>尝试复制文件或目录</td>
      <td>&gt;= 2.1.6</td>
    </tr>
    <tr>
      <td><a href="#os-trymv">os.trymv</a></td>
      <td>尝试移动重命名文件或目录</td>
      <td>&gt;= 2.1.6</td>
    </tr>
    <tr>
      <td><a href="#os-tryrm">os.tryrm</a></td>
      <td>尝试删除文件或目录树</td>
      <td>&gt;= 2.1.6</td>
    </tr>
    <tr>
      <td><a href="#os-cd">os.cd</a></td>
      <td>进入指定目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-rmdir">os.rmdir</a></td>
      <td>删除目录树</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-mkdir">os.mkdir</a></td>
      <td>创建指定目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-isdir">os.isdir</a></td>
      <td>判断目录是否存在</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-isfile">os.isfile</a></td>
      <td>判断文件是否存在</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-exists">os.exists</a></td>
      <td>判断文件或目录是否存在</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-dirs">os.dirs</a></td>
      <td>遍历获取指定目录下的所有目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-files">os.files</a></td>
      <td>遍历获取指定目录下的所有文件</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-filedirs">os.filedirs</a></td>
      <td>遍历获取指定目录下的所有文件或目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-run">os.run</a></td>
      <td>安静运行程序</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-runv">os.runv</a></td>
      <td>安静运行程序，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#os-exec">os.exec</a></td>
      <td>回显运行程序</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-execv">os.execv</a></td>
      <td>回显运行程序，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#os-iorun">os.iorun</a></td>
      <td>运行并获取程序输出内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-iorunv">os.iorunv</a></td>
      <td>运行并获取程序输出内容，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#os-getenv">os.getenv</a></td>
      <td>获取环境变量</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-setenv">os.setenv</a></td>
      <td>设置环境变量</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-tmpdir">os.tmpdir</a></td>
      <td>获取临时目录路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-tmpfile">os.tmpfile</a></td>
      <td>获取临时文件路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-curdir">os.curdir</a></td>
      <td>获取当前目录路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-filesize">os.filesize</a></td>
      <td>获取文件大小</td>
      <td>&gt;= 2.1.9</td>
    </tr>
    <tr>
      <td><a href="#os-scriptdir">os.scriptdir</a></td>
      <td>获取脚本目录路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-programdir">os.programdir</a></td>
      <td>获取xmake安装主程序脚本目录</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#os-projectdir">os.projectdir</a></td>
      <td>获取工程主目录</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#os-arch">os.arch</a></td>
      <td>获取当前系统架构</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#os-host">os.host</a></td>
      <td>获取当前主机系统</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="oscp">os.cp</h6>

<ul>
  <li>复制文件或目录</li>
</ul>

<p>行为和shell中的<code class="highlighter-rouge">cp</code>命令类似，支持路径通配符匹配（使用的是lua模式匹配），支持多文件复制，以及内置变量支持。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"$(scriptdir)/*.h"</span><span class="p">,</span> <span class="s2">"$(projectdir)/src/test/**.h"</span><span class="p">,</span> <span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面的代码将：当前<code class="highlighter-rouge">xmake.lua</code>目录下的所有头文件、工程源码test目录下的头文件全部复制到<code class="highlighter-rouge">$(buildir)</code>输出目录中。</p>

<p>其中<code class="highlighter-rouge">$(scriptdir)</code>, <code class="highlighter-rouge">$(projectdir)</code> 这些变量是xmake的内置变量，具体详情见：<a href="#内置变量">内置变量</a>的相关文档。</p>

<p>而<code class="highlighter-rouge">*.h</code>和<code class="highlighter-rouge">**.h</code>中的匹配模式，跟<a href="#targetadd_files">add_files</a>中的类似，前者是单级目录匹配，后者是递归多级目录匹配。</p>

<p>此接口同时支持目录的<code class="highlighter-rouge">递归复制</code>，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 递归复制当前目录到临时目录</span>
<span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"$(curdir)/test/"</span><span class="p">,</span> <span class="s2">"$(tmpdir)/test"</span><span class="p">)</span>
</code></pre>
</div>

<p class="tip">
尽量使用`os.cp`接口，而不是`os.run("cp ..")`，这样更能保证平台一致性，实现跨平台构建描述。
</p>

<h6 id="osmv">os.mv</h6>

<ul>
  <li>移动重命名文件或目录</li>
</ul>

<p>跟<a href="#os-cp">os.cp</a>的使用类似，同样支持多文件移动操作和模式匹配，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 移动多个文件到临时目录</span>
<span class="n">os</span><span class="p">.</span><span class="n">mv</span><span class="p">(</span><span class="s2">"$(buildir)/test1"</span><span class="p">,</span> <span class="s2">"$(buildir)/test2"</span><span class="p">,</span> <span class="s2">"$(tmpdir)"</span><span class="p">)</span>

<span class="c1">-- 文件移动不支持批量操作，也就是文件重命名</span>
<span class="n">os</span><span class="p">.</span><span class="n">mv</span><span class="p">(</span><span class="s2">"$(buildir)/libtest.a"</span><span class="p">,</span> <span class="s2">"$(buildir)/libdemo.a"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="osrm">os.rm</h6>

<ul>
  <li>删除文件或目录树</li>
</ul>

<p>支持递归删除目录，批量删除操作，以及模式匹配和内置变量，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">rm</span><span class="p">(</span><span class="s2">"$(buildir)/inc/**.h"</span><span class="p">,</span> <span class="s2">"$(buildir)/lib/"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="ostrycp">os.trycp</h6>

<ul>
  <li>尝试复制文件或目录</li>
</ul>

<p>跟<a href="#os-cp">os.cp</a>类似，唯一的区别就是，此接口操作失败不会抛出异常中断xmake，而是通过返回值标示是否执行成功。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">trycp</span><span class="p">(</span><span class="s2">"file"</span><span class="p">,</span> <span class="s2">"dest/file"</span><span class="p">)</span> <span class="k">then</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="ostrymv">os.trymv</h6>

<ul>
  <li>尝试移动文件或目录</li>
</ul>

<p>跟<a href="#os-mv">os.mv</a>类似，唯一的区别就是，此接口操作失败不会抛出异常中断xmake，而是通过返回值标示是否执行成功。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">trymv</span><span class="p">(</span><span class="s2">"file"</span><span class="p">,</span> <span class="s2">"dest/file"</span><span class="p">)</span> <span class="k">then</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="ostryrm">os.tryrm</h6>

<ul>
  <li>尝试删除文件或目录</li>
</ul>

<p>跟<a href="#os-rm">os.rm</a>类似，唯一的区别就是，此接口操作失败不会抛出异常中断xmake，而是通过返回值标示是否执行成功。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">tryrm</span><span class="p">(</span><span class="s2">"file"</span><span class="p">)</span> <span class="k">then</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="oscd">os.cd</h6>

<ul>
  <li>进入指定目录</li>
</ul>

<p>这个操作用于目录切换，同样也支持内置变量，但是不支持模式匹配和多目录处理，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 进入临时目录</span>
<span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">)</span>
</code></pre>
</div>

<p>如果要离开进入之前的目录，有多种方式：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 进入上级目录</span>
<span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">".."</span><span class="p">)</span>

<span class="c1">-- 进入先前的目录，相当于：cd -</span>
<span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">"-"</span><span class="p">)</span>

<span class="c1">-- 进入目录前保存之前的目录，用于之后跨级直接切回</span>
<span class="kd">local</span> <span class="n">oldir</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">"./src"</span><span class="p">)</span>
<span class="o">...</span>
<span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="n">oldir</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="osrmdir">os.rmdir</h6>

<ul>
  <li>仅删除目录</li>
</ul>

<p>如果不是目录就无法删除。</p>

<h6 id="osmkdir">os.mkdir</h6>

<ul>
  <li>创建目录</li>
</ul>

<p>支持批量创建和内置变量，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">mkdir</span><span class="p">(</span><span class="s2">"$(tmpdir)/test"</span><span class="p">,</span> <span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="osisdir">os.isdir</h6>

<ul>
  <li>判断是否为目录</li>
</ul>

<p>如果目录不存在，则返回false</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">isdir</span><span class="p">(</span><span class="s2">"src"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osisfile">os.isfile</h6>

<ul>
  <li>判断是否为文件</li>
</ul>

<p>如果文件不存在，则返回false</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">isfile</span><span class="p">(</span><span class="s2">"$(buildir)/libxxx.a"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osexists">os.exists</h6>

<ul>
  <li>判断文件或目录是否存在</li>
</ul>

<p>如果文件或目录不存在，则返回false</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 判断目录存在</span>
<span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">"$(buildir)"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>

<span class="c1">-- 判断文件存在</span>
<span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">"$(buildir)/libxxx.a"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ...</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osdirs">os.dirs</h6>

<ul>
  <li>遍历获取指定目录下的所有目录</li>
</ul>

<p>支持<a href="#targetadd_files">add_files</a>中的模式匹配，支持递归和非递归模式遍历，返回的结果是一个table数组，如果获取不到，返回空数组，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 递归遍历获取所有子目录</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">dir</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">dirs</span><span class="p">(</span><span class="s2">"$(buildir)/inc/**"</span><span class="p">))</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">dir</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osfiles">os.files</h6>

<ul>
  <li>遍历获取指定目录下的所有文件</li>
</ul>

<p>支持<a href="#targetadd_files">add_files</a>中的模式匹配，支持递归和非递归模式遍历，返回的结果是一个table数组，如果获取不到，返回空数组，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 非递归遍历获取所有子文件</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">filepath</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">files</span><span class="p">(</span><span class="s2">"$(buildir)/inc/*.h"</span><span class="p">))</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osfiledirs">os.filedirs</h6>

<ul>
  <li>遍历获取指定目录下的所有文件和目录</li>
</ul>

<p>支持<a href="#targetadd_files">add_files</a>中的模式匹配，支持递归和非递归模式遍历，返回的结果是一个table数组，如果获取不到，返回空数组，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 递归遍历获取所有子文件和目录</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">filedir</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">filedirs</span><span class="p">(</span><span class="s2">"$(buildir)/**"</span><span class="p">))</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">filedir</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="osrun">os.run</h6>

<ul>
  <li>安静运行原生shell命令</li>
</ul>

<p>用于执行第三方的shell命令，但不会回显输出，仅仅在出错后，高亮输出错误信息。</p>

<p>此接口支持参数格式化、内置变量，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 格式化参数传入</span>
<span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"echo hello %s!"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>

<span class="c1">-- 列举构建目录文件</span>
<span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ls -l $(buildir)"</span><span class="p">)</span>
</code></pre>
</div>

<p class="warning">
使用此接口执行shell命令，容易使构建跨平台性降低，对于`os.run("cp ..")`这种尽量使用`os.cp`代替。<br />
如果必须使用此接口运行shell程序，请自行使用[config.plat](#config-plat)接口判断平台支持。
</p>

<p>更加高级的进程运行和控制，见<a href="#process">process</a>模块接口。</p>

<h6 id="osrunv">os.runv</h6>

<ul>
  <li>安静运行原生shell命令，带参数列表</li>
</ul>

<p>跟<a href="#os-run">os.run</a>类似，只是传递参数的方式是通过参数列表传递，而不是字符串命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">runv</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="osexec">os.exec</h6>

<ul>
  <li>回显运行原生shell命令</li>
</ul>

<p>与<a href="#os-run">os.run</a>接口类似，唯一的不同是，此接口执行shell程序时，是带回显输出的，一般调试的时候用的比较多</p>

<h6 id="osexecv">os.execv</h6>

<ul>
  <li>回显运行原生shell命令，带参数列表</li>
</ul>

<p>跟<a href="#os-execv">os.execv</a>类似，只是传递参数的方式是通过参数列表传递，而不是字符串命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">execv</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="osiorun">os.iorun</h6>

<ul>
  <li>安静运行原生shell命令并获取输出内容</li>
</ul>

<p>与<a href="#os-run">os.run</a>接口类似，唯一的不同是，此接口执行shell程序后，会获取shell程序的执行结果，相当于重定向输出。</p>

<p>可同时获取<code class="highlighter-rouge">stdout</code>, <code class="highlighter-rouge">stderr</code>中的内容，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">outdata</span><span class="p">,</span> <span class="n">errdata</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">iorun</span><span class="p">(</span><span class="s2">"echo hello xmake!"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="osiorunv">os.iorunv</h6>

<ul>
  <li>安静运行原生shell命令并获取输出内容，带参数列表</li>
</ul>

<p>跟<a href="#os-iorunv">os.iorunv</a>类似，只是传递参数的方式是通过参数列表传递，而不是字符串命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">result</span><span class="p">,</span> <span class="n">errors</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">iorunv</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="osgetenv">os.getenv</h6>

<ul>
  <li>获取系统环境变量</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="nb">os.getenv</span><span class="p">(</span><span class="s2">"PATH"</span><span class="p">))</span>
</code></pre>
</div>

<h6 id="ossetenv">os.setenv</h6>

<ul>
  <li>设置系统环境变量</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">setenv</span><span class="p">(</span><span class="s2">"HOME"</span><span class="p">,</span> <span class="s2">"/tmp/"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="ostmpdir">os.tmpdir</h6>

<ul>
  <li>获取临时目录</li>
</ul>

<p>跟<a href="#var-tmpdir">$(tmpdir)</a>结果一致，只不过是直接获取返回一个变量，可以用后续字符串维护。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">tmpdir</span><span class="p">(),</span> <span class="s2">"file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>等价于：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="s2">"$(tmpdir)/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<h6 id="ostmpfile">os.tmpfile</h6>

<ul>
  <li>获取临时文件路径</li>
</ul>

<p>用于获取生成一个临时文件路径，仅仅是个路径，文件需要自己创建。</p>

<h6 id="oscurdir">os.curdir</h6>

<ul>
  <li>获取当前目录路径</li>
</ul>

<p>跟<a href="#var-curdir">$(curdir)</a>结果一致，只不过是直接获取返回一个变量，可以用后续字符串维护。</p>

<p>用法参考：<a href="#os-tmpdir">os.tmpdir</a>。</p>

<h6 id="osfilesize">os.filesize</h6>

<ul>
  <li>获取文件大小</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">filesize</span><span class="p">(</span><span class="s2">"/tmp/a"</span><span class="p">))</span>
</code></pre>
</div>

<h6 id="osscriptdir">os.scriptdir</h6>

<ul>
  <li>获取当前描述脚本的路径</li>
</ul>

<p>跟<a href="#var-scriptdir">$(scriptdir)</a>结果一致，只不过是直接获取返回一个变量，可以用后续字符串维护。</p>

<p>用法参考：<a href="#os-tmpdir">os.tmpdir</a>。</p>

<h6 id="osprogramdir">os.programdir</h6>

<ul>
  <li>获取xmake安装主程序脚本目录</li>
</ul>

<p>跟<a href="#var-programdir">$(programdir)</a>结果一致，只不过是直接获取返回一个变量，可以用后续字符串维护。</p>

<h6 id="osprojectdir">os.projectdir</h6>

<ul>
  <li>获取工程主目录</li>
</ul>

<p>跟<a href="#var-projectdir">$(projectdir)</a>结果一致，只不过是直接获取返回一个变量，可以用后续字符串维护。</p>

<h6 id="osarch">os.arch</h6>

<ul>
  <li>获取当前系统架构</li>
</ul>

<p>也就是当前主机系统的默认架构，例如我在<code class="highlighter-rouge">linux x86_64</code>上执行xmake进行构建，那么返回值是：<code class="highlighter-rouge">x86_64</code></p>

<h6 id="oshost">os.host</h6>

<ul>
  <li>获取当前主机的操作系统</li>
</ul>

<p>跟<a href="#var-host">$(host)</a>结果一致，例如我在<code class="highlighter-rouge">linux x86_64</code>上执行xmake进行构建，那么返回值是：<code class="highlighter-rouge">linux</code></p>

<h5 id="io">io</h5>

<p>io操作模块，扩展了lua内置的io模块，提供更多易用的接口。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#io-open">io.open</a></td>
      <td>打开文件用于读写</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-load">io.load</a></td>
      <td>从指定路径文件反序列化加载所有table内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-save">io.save</a></td>
      <td>序列化保存所有table内容到指定路径文件</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io.readfile">io.readfile</a></td>
      <td>从指定路径文件读取所有内容</td>
      <td>&gt;= 2.1.3</td>
    </tr>
    <tr>
      <td><a href="#io.writefile">io.writefile</a></td>
      <td>写入所有内容到指定路径文件</td>
      <td>&gt;= 2.1.3</td>
    </tr>
    <tr>
      <td><a href="#io-gsub">io.gsub</a></td>
      <td>全文替换指定路径文件的内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-tail">io.tail</a></td>
      <td>读取和显示文件的尾部内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-cat">io.cat</a></td>
      <td>读取和显示文件的所有内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-print">io.print</a></td>
      <td>带换行格式化输出内容到文件</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#io-printf">io.printf</a></td>
      <td>无换行格式化输出内容到文件</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="ioopen">io.open</h6>

<ul>
  <li>打开文件用于读写</li>
</ul>

<p>这个是属于lua的原生接口，详细使用可以参看lua的官方文档：<a href="https://www.lua.org/pil/21.2.html">The Complete I/O Model</a></p>

<p>如果要读取文件所有内容，可以这么写：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">io.open</span><span class="p">(</span><span class="s2">"$(tmpdir)/file.txt"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">file</span> <span class="k">then</span>
    <span class="kd">local</span> <span class="n">data</span> <span class="o">=</span> <span class="n">file</span><span class="p">:</span><span class="n">read</span><span class="p">(</span><span class="s2">"*all"</span><span class="p">)</span>
    <span class="n">file</span><span class="p">:</span><span class="n">close</span><span class="p">()</span>
<span class="k">end</span>
</code></pre>
</div>

<p>或者可以使用<a href="#io.readfile">io.readfile</a>更加快速地读取。</p>

<p>如果要写文件，可以这么操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 打开文件：w 为写模式, a 为追加写模式</span>
<span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="nb">io.open</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">file</span> <span class="k">then</span>

    <span class="c1">-- 用原生的lua接口写入数据到文件，不支持格式化，无换行，不支持内置变量</span>
    <span class="n">file</span><span class="p">:</span><span class="n">write</span><span class="p">(</span><span class="s2">"hello xmake\n"</span><span class="p">)</span>

    <span class="c1">-- 用xmake扩展的接口写入数据到文件，支持格式化，无换行，不支持内置变量</span>
    <span class="n">file</span><span class="p">:</span><span class="n">writef</span><span class="p">(</span><span class="s2">"hello %s\n"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>

    <span class="c1">-- 使用xmake扩展的格式化传参写入一行，带换行符，并且支持内置变量</span>
    <span class="n">file</span><span class="p">:</span><span class="nb">print</span><span class="p">(</span><span class="s2">"hello %s and $(buildir)"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>

    <span class="c1">-- 使用xmake扩展的格式化传参写入一行，无换行符，并且支持内置变量</span>
    <span class="n">file</span><span class="p">:</span><span class="n">printf</span><span class="p">(</span><span class="s2">"hello %s and $(buildir) \n"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>

    <span class="c1">-- 关闭文件</span>
    <span class="n">file</span><span class="p">:</span><span class="n">close</span><span class="p">()</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="ioload">io.load</h6>

<ul>
  <li>从指定路径文件反序列化加载所有table内容</li>
</ul>

<p>可以从文件中加载序列化好的table内容，一般与<a href="#io-save">io.save</a>配合使用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 加载序列化文件的内容到table</span>
<span class="kd">local</span> <span class="n">data</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span> <span class="k">then</span>

    <span class="c1">-- 在终端中dump打印整个table中内容，格式化输出</span>
    <span class="n">table</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="iosave">io.save</h6>

<ul>
  <li>序列化保存所有table内容到指定路径文件</li>
</ul>

<p>可以序列化存储table内容到指定文件，一般与<a href="#io-load">io.load</a>配合使用，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">save</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="p">{</span><span class="n">a</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s2">"b"</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s2">"c"</span><span class="p">})</span>
</code></pre>
</div>

<p>存储结果为：</p>

<div class="highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="err">[</span><span class="nt">"b"</span><span class="err">]</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"b"</span><span class="w">
</span><span class="err">,</span><span class="w">   </span><span class="err">[</span><span class="nt">"a"</span><span class="err">]</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"a"</span><span class="w">
</span><span class="err">,</span><span class="w">   </span><span class="err">[</span><span class="nt">"c"</span><span class="err">]</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"c"</span><span class="w">
</span><span class="err">}</span><span class="w">
</span></code></pre>
</div>

<h6 id="ioreadfile">io.readfile</h6>

<ul>
  <li>从指定路径文件读取所有内容</li>
</ul>

<p>可在不打开文件的情况下，直接读取整个文件的内容，更加的方便，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">data</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="iowritefile">io.writefile</h6>

<ul>
  <li>写入所有内容到指定路径文件</li>
</ul>

<p>可在不打开文件的情况下，直接写入整个文件的内容，更加的方便，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">writefile</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"all data"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="iogsub">io.gsub</h6>

<ul>
  <li>全文替换指定路径文件的内容</li>
</ul>

<p>类似<a href="#string-gsub">string.gsub</a>接口，全文模式匹配替换内容，不过这里是直接操作文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 移除文件所有的空白字符</span>
<span class="n">io</span><span class="p">.</span><span class="n">gsub</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"%s+"</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="iotail">io.tail</h6>

<ul>
  <li>读取和显示文件的尾部内容</li>
</ul>

<p>读取文件尾部指定行数的数据，并显示，类似<code class="highlighter-rouge">cat xxx.txt | tail -n 10</code>命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 显示文件最后10行内容</span>
<span class="n">io</span><span class="p">.</span><span class="n">tail</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="iocat">io.cat</h6>

<ul>
  <li>读取和显示文件的所有内容</li>
</ul>

<p>读取文件的所有内容并显示，类似<code class="highlighter-rouge">cat xxx.txt</code>命令，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">cat</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="ioprint">io.print</h6>

<ul>
  <li>带换行格式化输出内容到文件</li>
</ul>

<p>直接格式化传参输出一行字符串到文件，并且带换行，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"hello %s!"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="ioprintf">io.printf</h6>

<ul>
  <li>无换行格式化输出内容到文件</li>
</ul>

<p>直接格式化传参输出一行字符串到文件，不带换行，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"hello %s!\n"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="path">path</h5>

<p>路径操作模块，实现跨平台的路径操作，这是xmake的一个自定义的模块。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#path-join">path.join</a></td>
      <td>拼接路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-translate">path.translate</a></td>
      <td>转换路径到当前平台的路径风格</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-basename">path.basename</a></td>
      <td>获取路径最后不带后缀的文件名</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-filename">path.filename</a></td>
      <td>获取路径最后带后缀的文件名</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-extension">path.extension</a></td>
      <td>获取路径的后缀名</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-directory">path.directory</a></td>
      <td>获取路径最后的目录名</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-relative">path.relative</a></td>
      <td>转换成相对路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-absolute">path.absolute</a></td>
      <td>转换成绝对路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#path-is_absolute">path.is_absolute</a></td>
      <td>判断是否为绝对路径</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="pathjoin">path.join</h6>

<ul>
  <li>拼接路径</li>
</ul>

<p>将多个路径项进行追加拼接，由于<code class="highlighter-rouge">windows/unix</code>风格的路径差异，使用api来追加路径更加跨平台，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">,</span> <span class="s2">"dir1"</span><span class="p">,</span> <span class="s2">"dir2"</span><span class="p">,</span> <span class="s2">"file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>上述拼接在unix上相当于：<code class="highlighter-rouge">$(tmpdir)/dir1/dir2/file.txt</code>，而在windows上相当于：<code class="highlighter-rouge">$(tmpdir)\\dir1\\dir2\\file.txt</code></p>

<p>如果觉得这样很繁琐，不够清晰简洁，可以使用：<a href="path-translate">path.translate</a>方式，格式化转换路径字符串到当前平台支持的格式。</p>

<h6 id="pathtranslate">path.translate</h6>

<ul>
  <li>转换路径到当前平台的路径风格</li>
</ul>

<p>格式化转化指定路径字符串到当前平台支持的路径风格，同时支持<code class="highlighter-rouge">windows/unix</code>格式的路径字符串参数传入，甚至混合传入，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">translate</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">translate</span><span class="p">(</span><span class="s2">"$(tmpdir)\\dir\\file.txt"</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">translate</span><span class="p">(</span><span class="s2">"$(tmpdir)\\dir/dir2//file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>上面这三种不同格式的路径字符串，经过<code class="highlighter-rouge">translate</code>规范化后，就会变成当前平台支持的格式，并且会去掉冗余的路径分隔符。</p>

<h6 id="pathbasename">path.basename</h6>

<ul>
  <li>获取路径最后不带后缀的文件名</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">file</code></p>

<h6 id="pathfilename">path.filename</h6>

<ul>
  <li>获取路径最后带后缀的文件名</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">filename</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">file.txt</code></p>

<h6 id="pathextension">path.extension</h6>

<ul>
  <li>获取路径的后缀名</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">extensione</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">.txt</code></p>

<h6 id="pathdirectory">path.directory</h6>

<ul>
  <li>获取路径最后的目录名</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">directory</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">dir</code></p>

<h6 id="pathrelative">path.relative</h6>

<ul>
  <li>转换成相对路径</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">relative</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">,</span> <span class="s2">"$(tmpdir)"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">dir/file.txt</code></p>

<p>第二个参数是指定相对的根目录，如果不指定，则默认相对当前目录：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">relative</span><span class="p">(</span><span class="s2">"$(tmpdir)/dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>这样结果是一样的。</p>

<h6 id="pathabsolute">path.absolute</h6>

<ul>
  <li>转换成绝对路径</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">absolute</span><span class="p">(</span><span class="s2">"dir/file.txt"</span><span class="p">,</span> <span class="s2">"$(tmpdir)"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">$(tmpdir)/dir/file.txt</code></p>

<p>第二个参数是指定相对的根目录，如果不指定，则默认相对当前目录：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">cd</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">absolute</span><span class="p">(</span><span class="s2">"dir/file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>这样结果是一样的。</p>

<h6 id="pathis_absolute">path.is_absolute</h6>

<ul>
  <li>判断是否为绝对路径</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">path</span><span class="p">.</span><span class="n">is_absolute</span><span class="p">(</span><span class="s2">"/tmp/file.txt"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- 如果是绝对路径</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="table">table</h5>

<p>table属于lua原生提供的模块，对于原生接口使用可以参考：<a href="http://www.lua.org/manual/5.1/manual.html#5.5">lua官方文档</a></p>

<p>xmake中对其进行了扩展，增加了一些扩展接口：</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#table-join">table.join</a></td>
      <td>合并多个table并返回</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#table-join2">table.join2</a></td>
      <td>合并多个table到第一个table</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#table-dump">table.dump</a></td>
      <td>输出table的所有内容</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#table-unique">table.unique</a></td>
      <td>对table中的内容进行去重</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#table-slice">table.slice</a></td>
      <td>获取table的切片</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="tablejoin">table.join</h6>

<ul>
  <li>合并多个table并返回</li>
</ul>

<p>可以将多个table里面的元素进行合并后，返回到一个新的table中，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">newtable</span> <span class="o">=</span> <span class="n">table</span><span class="p">.</span><span class="n">join</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">},</span> <span class="p">{</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">},</span> <span class="p">{</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">})</span>
</code></pre>
</div>

<p>结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">1,</span><span class="w"> </span><span class="err">2,</span><span class="w"> </span><span class="err">3,</span><span class="w"> </span><span class="err">4,</span><span class="w"> </span><span class="err">5,</span><span class="w"> </span><span class="err">6,</span><span class="w"> </span><span class="err">7,</span><span class="w"> </span><span class="err">8,</span><span class="w"> </span><span class="err">9</span><span class="p">}</span></code></p>

<p>并且它也支持字典的合并：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">newtable</span> <span class="o">=</span> <span class="n">table</span><span class="p">.</span><span class="n">join</span><span class="p">({</span><span class="n">a</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="s2">"b"</span><span class="p">},</span> <span class="p">{</span><span class="n">c</span> <span class="o">=</span> <span class="s2">"c"</span><span class="p">},</span> <span class="p">{</span><span class="n">d</span> <span class="o">=</span> <span class="s2">"d"</span><span class="p">})</span>
</code></pre>
</div>

<p>结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">a</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"a"</span><span class="err">,</span><span class="w"> </span><span class="err">b</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"b"</span><span class="err">,</span><span class="w"> </span><span class="err">c</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"c"</span><span class="err">,</span><span class="w"> </span><span class="err">d</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"d"</span><span class="err">}</span></code></p>

<h6 id="tablejoin2">table.join2</h6>

<ul>
  <li>合并多个table到第一个table</li>
</ul>

<p>类似<a href="#table.join">table.join</a>，唯一的区别是，合并的结果放置在第一个参数中，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">t</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">9</span><span class="p">}</span>
<span class="n">table</span><span class="p">.</span><span class="n">join2</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">})</span>
</code></pre>
</div>

<p>结果为：<code class="highlighter-rouge">t = {0, 9, 1, 2, 3}</code></p>

<h6 id="tabledump">table.dump</h6>

<ul>
  <li>输出table的所有内容</li>
</ul>

<p>递归格式化打印table中的所有内容，一般用于调试， 例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">table</span><span class="p">.</span><span class="n">dump</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">})</span>
</code></pre>
</div>

<p>结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">1,</span><span class="w"> </span><span class="err">2,</span><span class="w"> </span><span class="err">3</span><span class="p">}</span></code></p>

<h6 id="tableunique">table.unique</h6>

<ul>
  <li>对table中的内容进行去重</li>
</ul>

<p>去重table的元素，一般用于数组table，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">newtable</span> <span class="o">=</span> <span class="n">table</span><span class="p">.</span><span class="n">unique</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">})</span>
</code></pre>
</div>

<p>结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">1,</span><span class="w"> </span><span class="err">2,</span><span class="w"> </span><span class="err">3,</span><span class="w"> </span><span class="err">4,</span><span class="w"> </span><span class="err">5</span><span class="p">}</span></code></p>

<h6 id="tableslice">table.slice</h6>

<ul>
  <li>获取table的切片</li>
</ul>

<p>用于提取数组table的部分元素，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 提取第4个元素后面的所有元素，结果：{4, 5, 6, 7, 8, 9}</span>
<span class="n">table</span><span class="p">.</span><span class="n">slice</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">},</span> <span class="mi">4</span><span class="p">)</span>

<span class="c1">-- 提取第4-8个元素，结果：{4, 5, 6, 7, 8}</span>
<span class="n">table</span><span class="p">.</span><span class="n">slice</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">},</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span>

<span class="c1">-- 提取第4-8个元素，间隔步长为2，结果：{4, 6, 8}</span>
<span class="n">table</span><span class="p">.</span><span class="n">slice</span><span class="p">({</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">},</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="string">string</h5>

<p>字符串模块为lua原生自带的模块，具体使用见：<a href="http://www.lua.org/manual/5.1/manual.html#5.4">lua官方手册</a></p>

<p>xmake中对其进行了扩展，增加了一些扩展接口：</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#string-startswith">string.startswith</a></td>
      <td>判断字符串开头是否匹配</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#string-endswith">string.endswith</a></td>
      <td>判断字符串结尾是否匹配</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#string-split">string.split</a></td>
      <td>分割字符串</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#string-trim">string.trim</a></td>
      <td>去掉字符串左右空白字符</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#string-ltrim">string.ltrim</a></td>
      <td>去掉字符串左边空白字符</td>
      <td>&gt;= 1.0.1</td>
    </tr>
    <tr>
      <td><a href="#string-rtrim">string.rtrim</a></td>
      <td>去掉字符串右边空白字符</td>
      <td>&gt;= 1.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="stringstartswith">string.startswith</h6>

<ul>
  <li>判断字符串开头是否匹配</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="s2">"hello xmake"</span>
<span class="k">if</span> <span class="n">s</span><span class="p">:</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span> <span class="k">then</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"match"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="stringendswith">string.endswith</h6>

<ul>
  <li>判断字符串结尾是否匹配</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="s2">"hello xmake"</span>
<span class="k">if</span> <span class="n">s</span><span class="p">:</span><span class="n">endswith</span><span class="p">(</span><span class="s2">"xmake"</span><span class="p">)</span> <span class="k">then</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"match"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="stringsplit">string.split</h6>

<ul>
  <li>分割字符串</li>
</ul>

<p>通过指定的分隔符进行字符串分割，分隔符可以是：字符，字符串、模式匹配字符串，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="s2">"hello     xmake!"</span>
<span class="n">s</span><span class="p">:</span><span class="n">split</span><span class="p">(</span><span class="s2">"%s+"</span><span class="p">)</span>
</code></pre>
</div>

<p>根据连续空白字符进行分割，结果为：<code class="highlighter-rouge">hello</code>, <code class="highlighter-rouge">xmake!</code></p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">s</span> <span class="o">=</span> <span class="s2">"hello,xmake:123"</span>
<span class="n">s</span><span class="p">:</span><span class="n">split</span><span class="p">(</span><span class="s2">"[,:]"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面的代码根据<code class="highlighter-rouge">,</code>或者<code class="highlighter-rouge">:</code>字符进行分割，结果为：<code class="highlighter-rouge">hello</code>, <code class="highlighter-rouge">xmake</code>, <code class="highlighter-rouge">123</code></p>

<h6 id="stringtrim">string.trim</h6>

<ul>
  <li>去掉字符串左右空白字符</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">string</span><span class="p">.</span><span class="n">trim</span><span class="p">(</span><span class="s2">"    hello xmake!    "</span><span class="p">)</span>
</code></pre>
</div>

<p>结果为：”hello xmake!”</p>

<h6 id="stringltrim">string.ltrim</h6>

<ul>
  <li>去掉字符串左边空白字符</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">string</span><span class="p">.</span><span class="n">ltrim</span><span class="p">(</span><span class="s2">"    hello xmake!    "</span><span class="p">)</span>
</code></pre>
</div>

<p>结果为：”hello xmake!    “</p>

<h6 id="stringrtrim">string.rtrim</h6>

<ul>
  <li>去掉字符串右边空白字符</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">string</span><span class="p">.</span><span class="n">rtrim</span><span class="p">(</span><span class="s2">"    hello xmake!    "</span><span class="p">)</span>
</code></pre>
</div>

<p>结果为：”    hello xmake!”</p>

<h5 id="process">process</h5>

<p>这个是xmake扩展的进程控制模块，用于更加灵活的控制进程，比起：<a href="#os-run">os.run</a>系列灵活性更高，也更底层。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#process-open">process.open</a></td>
      <td>打开进程</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#process-wait">process.wait</a></td>
      <td>等待进程结束</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#process-close">process.close</a></td>
      <td>关闭进程对象</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#process-waitlist">process.waitlist</a></td>
      <td>同时等待多个进程</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="processopen">process.open</h6>

<ul>
  <li>打开进程</li>
</ul>

<p>通过路径创建运行一个指定程序，并且返回对应的进程对象：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 打开进程，后面两个参数指定需要捕获的stdout, stderr文件路径</span>
<span class="kd">local</span> <span class="n">proc</span> <span class="o">=</span> <span class="n">process</span><span class="p">.</span><span class="n">open</span><span class="p">(</span><span class="s2">"echo hello xmake!"</span><span class="p">,</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">errfile</span><span class="p">)</span>
<span class="k">if</span> <span class="n">proc</span> <span class="k">then</span>

    <span class="c1">-- 等待进程执行完成</span>
    <span class="c1">--</span>
    <span class="c1">-- 参数二为等待超时，-1为永久等待，0为尝试获取进程状态</span>
    <span class="c1">-- 返回值waitok为等待状态：1为等待进程正常结束，0为进程还在运行中，-1位等待失败</span>
    <span class="c1">-- 返回值status为，等待进程结束后，进程返回的状态码</span>
    <span class="kd">local</span> <span class="n">waitok</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="n">process</span><span class="p">.</span><span class="n">wait</span><span class="p">(</span><span class="n">proc</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>

    <span class="c1">-- 释放进程对象</span>
    <span class="n">process</span><span class="p">.</span><span class="n">close</span><span class="p">(</span><span class="n">proc</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="processwait">process.wait</h6>

<ul>
  <li>等待进程结束</li>
</ul>

<p>具体使用见：<a href="#process-open">process.open</a></p>

<h6 id="processclose">process.close</h6>

<ul>
  <li>关闭进程对象</li>
</ul>

<p>具体使用见：<a href="#process-open">process.open</a></p>

<h6 id="processwaitlist">process.waitlist</h6>

<ul>
  <li>同时等待多个进程</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 第二个参数是等待超时，返回进程状态列表</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">procinfo</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">process</span><span class="p">.</span><span class="n">waitlist</span><span class="p">(</span><span class="n">procs</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">))</span> <span class="k">do</span>
    
    <span class="c1">-- 每个进程的：进程对象、进程pid、进程结束状态码</span>
    <span class="kd">local</span> <span class="n">proc</span>      <span class="o">=</span> <span class="n">procinfo</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="kd">local</span> <span class="n">procid</span>    <span class="o">=</span> <span class="n">procinfo</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
    <span class="kd">local</span> <span class="n">status</span>    <span class="o">=</span> <span class="n">procinfo</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>

<span class="k">end</span>
</code></pre>
</div>

<h5 id="coroutine">coroutine</h5>

<p>协程模块是lua原生自带的模块，具使用见：<a href="http://www.lua.org/manual/5.1/manual.html#5.2">lua官方手册</a></p>

<h4 id="extension-modules">Extension Modules</h4>

<p>所有扩展模块的使用，都需要通过<a href="#import">import</a>接口，进行导入后才能使用。</p>

<h5 id="corebaseoption">core.base.option</h5>

<p>一般用于获取xmake命令参数选项的值，常用于插件开发。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#option-get">option.get</a></td>
      <td>获取参数选项值</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="optionget">option.get</h6>

<ul>
  <li>获取参数选项值</li>
</ul>

<p>在插件开发中用于获取参数选项值，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 导入选项模块</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>

<span class="c1">-- 插件入口函数</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"info"</span><span class="p">))</span>
<span class="k">end</span>
</code></pre>
</div>

<p>上面的代码获取hello插件，执行：<code class="highlighter-rouge">xmake hello --info=xxxx</code> 命令时候传入的<code class="highlighter-rouge">--info=</code>选项的值，并显示：<code class="highlighter-rouge">xxxx</code></p>

<p>对于非main入口的task任务或插件，可以这么使用：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">())</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"info"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="corebaseglobal">core.base.global</h5>

<p>用于获取xmake全局的配置信息，也就是<code class="highlighter-rouge">xmake g|global --xxx=val</code> 传入的参数选项值。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#global-get">global.get</a></td>
      <td>获取指定配置值</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#global-load">global.load</a></td>
      <td>加载配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#global-directory">global.directory</a></td>
      <td>获取全局配置信息目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#global-dump">global.dump</a></td>
      <td>打印输出所有全局配置信息</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<p class="tip">
2.1.5版本之前为`core.project.global`。
</p>

<h6 id="globalget">global.get</h6>

<ul>
  <li>获取指定配置值</li>
</ul>

<p>类似<a href="#config-get">config.get</a>，唯一的区别就是这个是从全局配置中获取。</p>

<h6 id="globalload">global.load</h6>

<ul>
  <li>加载配置</li>
</ul>

<p>类似<a href="#global-get">global.get</a>，唯一的区别就是这个是从全局配置中加载。</p>

<h6 id="globaldirectory">global.directory</h6>

<ul>
  <li>获取全局配置信息目录</li>
</ul>

<p>默认为<code class="highlighter-rouge">~/.config</code>目录。</p>

<h6 id="globaldump">global.dump</h6>

<ul>
  <li>打印输出所有全局配置信息</li>
</ul>

<p>输出结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
    <span class="n">clean</span> <span class="o">=</span> <span class="kc">true</span>
<span class="p">,</span>   <span class="n">ccache</span> <span class="o">=</span> <span class="s2">"ccache"</span>
<span class="p">,</span>   <span class="n">xcode_dir</span> <span class="o">=</span> <span class="s2">"/Applications/Xcode.app"</span>
<span class="p">}</span>
</code></pre>
</div>

<h5 id="corebasetask">core.base.task</h5>

<p>用于任务操作，一般用于在自定义脚本中、插件任务中，调用运行其他task任务。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#task-run">task.run</a></td>
      <td>运行指定任务</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<p class="tip">
2.1.5版本之前为`core.project.task`。
</p>

<h6 id="taskrun">task.run</h6>

<ul>
  <li>运行指定任务</li>
</ul>

<p>用于在自定义脚本、插件任务中运行<a href="#task">task</a>定义的任务或插件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">on_clean</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>

        <span class="c1">-- 导入task模块</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>

        <span class="c1">-- 运行这个hello task</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>我们还可以在运行任务时，增加参数传递，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">task</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake: %s %s!"</span><span class="p">,</span> <span class="n">arg1</span><span class="p">,</span> <span class="n">arg2</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>

<span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">on_clean</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>

        <span class="c1">-- 导入task</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>

        <span class="c1">-- {} 这个是给第一种选项传参使用，这里置空，这里在最后面传入了两个参数：arg1, arg2</span>
        <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">,</span> <span class="p">{},</span> <span class="s2">"arg1"</span><span class="p">,</span> <span class="s2">"arg2"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>对于<code class="highlighter-rouge">task.run</code>的第二个参数，用于传递命令行菜单中的选项，而不是直接传入<code class="highlighter-rouge">function (arg, ...)</code>函数入口中，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 导入task</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>

<span class="c1">-- 插件入口</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>

    <span class="c1">-- 运行内置的xmake配置任务，相当于：xmake f|config --plat=iphoneos --arch=armv7</span>
    <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"config"</span><span class="p">,</span> <span class="p">{</span><span class="n">plat</span><span class="o">=</span><span class="s2">"iphoneos"</span><span class="p">,</span> <span class="n">arch</span><span class="o">=</span><span class="s2">"armv7"</span><span class="p">})</span>
<span class="n">emd</span>
</code></pre>
</div>

<h5 id="coretoollinker">core.tool.linker</h5>

<p>链接器相关操作，常用于插件开发。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#linker-link">linker.link</a></td>
      <td>执行链接</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#linker-linkcmd">linker.linkcmd</a></td>
      <td>获取链接命令行</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#linker-linkargv">linker.linkargv</a></td>
      <td>获取链接命令行列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#linker-linkflags">linker.linkflags</a></td>
      <td>获取链接选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#linker-has_flags">linker.has_flags</a></td>
      <td>判断指定链接选项是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="linkerlink">linker.link</h6>

<ul>
  <li>执行链接</li>
</ul>

<p>针对target，链接指定对象文件列表，生成对应的目标文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">linker</span><span class="p">.</span><span class="n">link</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">,</span> <span class="s2">"cc"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">(),</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
</code></pre>
</div>

<p>其中<a href="#target">target</a>，为工程目标，这里传入，主要用于获取target特定的链接选项，具体如果获取工程目标对象，见：<a href="#core-project-project">core.project.project</a></p>

<p>当然也可以不指定target，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">linker</span><span class="p">.</span><span class="n">link</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">,</span> <span class="s2">"cc"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="s2">"/tmp/targetfile"</span><span class="p">)</span>
</code></pre>
</div>

<p>第一个参数指定链接类型，目前支持：binary, static, shared
第二个参数告诉链接器，应该作为那种源文件对象进行链接，这些对象源文件使用什么编译器编译的，例如：</p>

<table>
  <thead>
    <tr>
      <th>第二个参数值</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cc</td>
      <td>c编译器</td>
    </tr>
    <tr>
      <td>cxx</td>
      <td>c++编译器</td>
    </tr>
    <tr>
      <td>mm</td>
      <td>objc编译器</td>
    </tr>
    <tr>
      <td>mxx</td>
      <td>objc++编译器</td>
    </tr>
    <tr>
      <td>gc</td>
      <td>go编译器</td>
    </tr>
    <tr>
      <td>as</td>
      <td>汇编器</td>
    </tr>
    <tr>
      <td>sc</td>
      <td>swift编译器</td>
    </tr>
    <tr>
      <td>rc</td>
      <td>rust编译器</td>
    </tr>
    <tr>
      <td>dc</td>
      <td>dlang编译器</td>
    </tr>
  </tbody>
</table>

<p>指定不同的编译器类型，链接器会适配最合适的链接器来处理链接，并且如果几种支持混合编译的语言，那么可以同时传入多个编译器类型，指定链接器选择支持这些混合编译语言的链接器进行链接处理：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">linker</span><span class="p">.</span><span class="n">link</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"cc"</span><span class="p">,</span> <span class="s2">"mxx"</span><span class="p">,</span> <span class="s2">"sc"</span><span class="p">},</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="s2">"/tmp/targetfile"</span><span class="p">)</span>
</code></pre>
</div>

<p>上述代码告诉链接器，a, b, c三个对象文件有可能分别是c, objc++, swift代码编译出来的，链接器会从当前系统和工具链中选择最合适的链接器去处理这个链接过程。</p>

<h6 id="linkerlinkcmd">linker.linkcmd</h6>

<ul>
  <li>获取链接命令行字符串</li>
</ul>

<p>直接获取<a href="#linker-link">linker.link</a>中执行的命令行字符串，相当于：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">cmdstr</span> <span class="o">=</span> <span class="n">linker</span><span class="p">.</span><span class="n">linkcmd</span><span class="p">(</span><span class="s2">"static"</span><span class="p">,</span> <span class="s2">"cxx"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">(),</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
</code></pre>
</div>

<p>注：后面<code class="highlighter-rouge"><span class="p">{</span><span class="err">target</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">target</span><span class="p">}</span></code>扩展参数部分是可选的，如果传递了target对象，那么生成的链接命令，会加上这个target配置对应的链接选项。</p>

<p>并且还可以自己传递各种配置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">cmdstr</span> <span class="o">=</span> <span class="n">linker</span><span class="p">.</span><span class="n">linkcmd</span><span class="p">(</span><span class="s2">"static"</span><span class="p">,</span> <span class="s2">"cxx"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">(),</span> <span class="p">{</span><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="n">linkdirs</span> <span class="o">=</span> <span class="s2">"/usr/lib"</span><span class="p">}})</span>
</code></pre>
</div>

<h6 id="linkerlinkargv">linker.linkargv</h6>

<ul>
  <li>获取链接命令行参数列表</li>
</ul>

<p>跟<a href="#linker-linkcmd">linker.linkcmd</a>稍微有点区别的是，此接口返回的是参数列表，table表示，更加方便操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">program</span><span class="p">,</span> <span class="n">argv</span> <span class="o">=</span> <span class="n">linker</span><span class="p">.</span><span class="n">linkargv</span><span class="p">(</span><span class="s2">"static"</span><span class="p">,</span> <span class="s2">"cxx"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a.o"</span><span class="p">,</span> <span class="s2">"b.o"</span><span class="p">,</span> <span class="s2">"c.o"</span><span class="p">},</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">(),</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
</code></pre>
</div>

<p>其中返回的第一个值是主程序名，后面是参数列表，而<code class="highlighter-rouge">os.args(table.join(program, argv))</code>等价于<code class="highlighter-rouge">linker.linkcmd</code>。</p>

<p>我们也可以通过传入返回值给<a href="#os-runv">os.runv</a>来直接运行它：<code class="highlighter-rouge">os.runv(linker.linkargv(..))</code></p>

<h6 id="linkerlinkflags">linker.linkflags</h6>

<ul>
  <li>获取链接选项</li>
</ul>

<p>获取<a href="#linker-linkcmd">linker.linkcmd</a>中的链接选项字符串部分，不带shellname和对象文件列表，并且是按数组返回，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">flags</span> <span class="o">=</span> <span class="n">linker</span><span class="p">.</span><span class="n">linkflags</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">,</span> <span class="s2">"cc"</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">flag</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">flags</span><span class="p">)</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>返回的是flags的列表数组。</p>

<h6 id="linkerhas_flags">linker.has_flags</h6>

<ul>
  <li>判断指定链接选项是否支持</li>
</ul>

<p>虽然通过<a href="detect-has_flags">lib.detect.has_flags</a>也能判断，但是那个接口更加底层，需要指定链接器名称
而此接口只需要指定target的目标类型，源文件类型，它会自动切换选择当前支持的链接器。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">linker</span><span class="p">.</span><span class="n">has_flags</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetkind</span><span class="p">(),</span> <span class="n">target</span><span class="p">:</span><span class="n">sourcekinds</span><span class="p">(),</span> <span class="s2">"-L/usr/lib -lpthread"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>
</code></pre>
</div>

<h5 id="coretoolcompiler">core.tool.compiler</h5>

<p>编译器相关操作，常用于插件开发。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#compiler-compile">compiler.compile</a></td>
      <td>执行编译</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#compiler-compcmd">compiler.compcmd</a></td>
      <td>获取编译命令行</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#compiler-compargv">compiler.compargv</a></td>
      <td>获取编译命令行列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#compiler-compflags">compiler.compflags</a></td>
      <td>获取编译选项</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#compiler-has_flags">compiler.has_flags</a></td>
      <td>判断指定编译选项是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#compiler-features">compiler.features</a></td>
      <td>获取所有编译器特性</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#compiler-has_features">compiler.has_features</a></td>
      <td>判断指定编译特性是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="compilercompile">compiler.compile</h6>

<ul>
  <li>执行编译</li>
</ul>

<p>针对target，链接指定对象文件列表，生成对应的目标文件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">compiler</span><span class="p">.</span><span class="n">compile</span><span class="p">(</span><span class="s2">"xxx.c"</span><span class="p">,</span> <span class="s2">"xxx.o"</span><span class="p">,</span> <span class="s2">"xxx.h.d"</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
</code></pre>
</div>

<p>其中<a href="#target">target</a>，为工程目标，这里传入主要用于获取taeget的特定编译选项，具体如果获取工程目标对象，见：<a href="#core-project-project">core.project.project</a></p>

<p>而<code class="highlighter-rouge">xxx.h.d</code>文件用于存储为此源文件的头文件依赖文件列表，最后这两个参数都是可选的，编译的时候可以不传他们：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">compiler</span><span class="p">.</span><span class="n">compile</span><span class="p">(</span><span class="s2">"xxx.c"</span><span class="p">,</span> <span class="s2">"xxx.o"</span><span class="p">)</span>
</code></pre>
</div>

<p>来单纯编译一个源文件。</p>

<h6 id="compilercompcmd">compiler.compcmd</h6>

<ul>
  <li>获取编译命令行</li>
</ul>

<p>直接获取<a href="#compiler-compile">compiler.compile</a>中执行的命令行字符串，相当于：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">cmdstr</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">compcmd</span><span class="p">(</span><span class="s2">"xxx.c"</span><span class="p">,</span> <span class="s2">"xxx.o"</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
</code></pre>
</div>

<p>注：后面<code class="highlighter-rouge"><span class="p">{</span><span class="err">target</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">target</span><span class="p">}</span></code>扩展参数部分是可选的，如果传递了target对象，那么生成的编译命令，会加上这个target配置对应的链接选项。</p>

<p>并且还可以自己传递各种配置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">cmdstr</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">compcmd</span><span class="p">(</span><span class="s2">"xxx.c"</span><span class="p">,</span> <span class="s2">"xxx.o"</span><span class="p">,</span> <span class="p">{</span><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="n">includedirs</span> <span class="o">=</span> <span class="s2">"/usr/include"</span><span class="p">,</span> <span class="n">defines</span> <span class="o">=</span> <span class="s2">"DEBUG"</span><span class="p">}})</span>
</code></pre>
</div>

<p>通过target，我们可以导出指定目标的所有源文件编译命令：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.project.project"</span><span class="p">)</span>

<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">target</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">project</span><span class="p">.</span><span class="n">targets</span><span class="p">())</span> <span class="k">do</span>
    <span class="k">for</span> <span class="n">sourcekind</span><span class="p">,</span> <span class="n">sourcebatch</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">sourcebatches</span><span class="p">())</span> <span class="k">do</span>
        <span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">objectfile</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">sourcebatch</span><span class="p">.</span><span class="n">objectfiles</span><span class="p">)</span> <span class="k">do</span>
            <span class="kd">local</span> <span class="n">cmdstr</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">compcmd</span><span class="p">(</span><span class="n">sourcebatch</span><span class="p">.</span><span class="n">sourcefiles</span><span class="p">[</span><span class="n">index</span><span class="p">],</span> <span class="n">objectfile</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
        <span class="k">end</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="compilercompargv">compiler.compargv</h6>

<ul>
  <li>获取编译命令行列表</li>
</ul>

<p>跟<a href="#compiler-compargv">compiler.compargv</a>稍微有点区别的是，此接口返回的是参数列表，table表示，更加方便操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">program</span><span class="p">,</span> <span class="n">argv</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">compargv</span><span class="p">(</span><span class="s2">"xxx.c"</span><span class="p">,</span> <span class="s2">"xxx.o"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="compilercompflags">compiler.compflags</h6>

<ul>
  <li>获取编译选项</li>
</ul>

<p>获取<a href="#compiler-compcmd">compiler.compcmd</a>中的编译选项字符串部分，不带shellname和文件列表，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">flags</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">compflags</span><span class="p">(</span><span class="n">sourcefile</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">flag</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">(</span><span class="n">flags</span><span class="p">)</span> <span class="k">do</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>返回的是flags的列表数组。</p>

<h6 id="compilerhas_flags">compiler.has_flags</h6>

<ul>
  <li>判断指定编译选项是否支持</li>
</ul>

<p>虽然通过<a href="detect-has_flags">lib.detect.has_flags</a>也能判断，但是那个接口更加底层，需要指定编译器名称。
而此接口只需要指定语言类型，它会自动切换选择当前支持的编译器。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 判断c语言编译器是否支持选项: -g</span>
<span class="k">if</span> <span class="n">compiler</span><span class="p">.</span><span class="n">has_flags</span><span class="p">(</span><span class="s2">"c"</span><span class="p">,</span> <span class="s2">"-g"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>

<span class="c1">-- 判断c++语言编译器是否支持选项: -g</span>
<span class="k">if</span> <span class="n">compiler</span><span class="p">.</span><span class="n">has_flags</span><span class="p">(</span><span class="s2">"cxx"</span><span class="p">,</span> <span class="s2">"-g"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="compilerfeatures">compiler.features</h6>

<ul>
  <li>获取所有编译器特性</li>
</ul>

<p>虽然通过<a href="detect-features">lib.detect.features</a>也能获取，但是那个接口更加底层，需要指定编译器名称。
而此接口只需要指定语言类型，它会自动切换选择当前支持的编译器，然后获取当前的编译器特性列表。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 获取当前c语言编译器的所有特性</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">features</span><span class="p">(</span><span class="s2">"c"</span><span class="p">)</span>

<span class="c1">-- 获取当前c++语言编译器的所有特性，启用c++11标准，否则获取不到新标准的特性</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">features</span><span class="p">(</span><span class="s2">"cxx"</span><span class="p">,</span> <span class="p">{</span><span class="n">cofnig</span> <span class="o">=</span> <span class="p">{</span><span class="n">cxxflags</span> <span class="o">=</span> <span class="s2">"-std=c++11"</span><span class="p">}})</span>

<span class="c1">-- 获取当前c++语言编译器的所有特性，传递工程target的所有配置信息</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">features</span><span class="p">(</span><span class="s2">"cxx"</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">,</span> <span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="n">defines</span> <span class="o">=</span> <span class="s2">".."</span><span class="p">,</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="s2">".."</span><span class="p">}})</span>
</code></pre>
</div>

<p>所有c编译器特性列表：</p>

<table>
  <thead>
    <tr>
      <th>特性名</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>c_static_assert</td>
    </tr>
    <tr>
      <td>c_restrict</td>
    </tr>
    <tr>
      <td>c_variadic_macros</td>
    </tr>
    <tr>
      <td>c_function_prototypes</td>
    </tr>
  </tbody>
</table>

<p>所有c++编译器特性列表：</p>

<table>
  <thead>
    <tr>
      <th>特性名</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cxx_variable_templates</td>
    </tr>
    <tr>
      <td>cxx_relaxed_constexpr</td>
    </tr>
    <tr>
      <td>cxx_aggregate_default_initializers</td>
    </tr>
    <tr>
      <td>cxx_contextual_conversions</td>
    </tr>
    <tr>
      <td>cxx_attribute_deprecated</td>
    </tr>
    <tr>
      <td>cxx_decltype_auto</td>
    </tr>
    <tr>
      <td>cxx_digit_separators</td>
    </tr>
    <tr>
      <td>cxx_generic_lambdas</td>
    </tr>
    <tr>
      <td>cxx_lambda_init_captures</td>
    </tr>
    <tr>
      <td>cxx_binary_literals</td>
    </tr>
    <tr>
      <td>cxx_return_type_deduction</td>
    </tr>
    <tr>
      <td>cxx_decltype_incomplete_return_types</td>
    </tr>
    <tr>
      <td>cxx_reference_qualified_functions</td>
    </tr>
    <tr>
      <td>cxx_alignof</td>
    </tr>
    <tr>
      <td>cxx_attributes</td>
    </tr>
    <tr>
      <td>cxx_inheriting_constructors</td>
    </tr>
    <tr>
      <td>cxx_thread_local</td>
    </tr>
    <tr>
      <td>cxx_alias_templates</td>
    </tr>
    <tr>
      <td>cxx_delegating_constructors</td>
    </tr>
    <tr>
      <td>cxx_extended_friend_declarations</td>
    </tr>
    <tr>
      <td>cxx_final</td>
    </tr>
    <tr>
      <td>cxx_nonstatic_member_init</td>
    </tr>
    <tr>
      <td>cxx_override</td>
    </tr>
    <tr>
      <td>cxx_user_literals</td>
    </tr>
    <tr>
      <td>cxx_constexpr</td>
    </tr>
    <tr>
      <td>cxx_defaulted_move_initializers</td>
    </tr>
    <tr>
      <td>cxx_enum_forward_declarations</td>
    </tr>
    <tr>
      <td>cxx_noexcept</td>
    </tr>
    <tr>
      <td>cxx_nullptr</td>
    </tr>
    <tr>
      <td>cxx_range_for</td>
    </tr>
    <tr>
      <td>cxx_unrestricted_unions</td>
    </tr>
    <tr>
      <td>cxx_explicit_conversions</td>
    </tr>
    <tr>
      <td>cxx_lambdas</td>
    </tr>
    <tr>
      <td>cxx_local_type_template_args</td>
    </tr>
    <tr>
      <td>cxx_raw_string_literals</td>
    </tr>
    <tr>
      <td>cxx_auto_type</td>
    </tr>
    <tr>
      <td>cxx_defaulted_functions</td>
    </tr>
    <tr>
      <td>cxx_deleted_functions</td>
    </tr>
    <tr>
      <td>cxx_generalized_initializers</td>
    </tr>
    <tr>
      <td>cxx_inline_namespaces</td>
    </tr>
    <tr>
      <td>cxx_sizeof_member</td>
    </tr>
    <tr>
      <td>cxx_strong_enums</td>
    </tr>
    <tr>
      <td>cxx_trailing_return_types</td>
    </tr>
    <tr>
      <td>cxx_unicode_literals</td>
    </tr>
    <tr>
      <td>cxx_uniform_initialization</td>
    </tr>
    <tr>
      <td>cxx_variadic_templates</td>
    </tr>
    <tr>
      <td>cxx_decltype</td>
    </tr>
    <tr>
      <td>cxx_default_function_template_args</td>
    </tr>
    <tr>
      <td>cxx_long_long_type</td>
    </tr>
    <tr>
      <td>cxx_right_angle_brackets</td>
    </tr>
    <tr>
      <td>cxx_rvalue_references</td>
    </tr>
    <tr>
      <td>cxx_static_assert</td>
    </tr>
    <tr>
      <td>cxx_extern_templates</td>
    </tr>
    <tr>
      <td>cxx_func_identifier</td>
    </tr>
    <tr>
      <td>cxx_variadic_macros</td>
    </tr>
    <tr>
      <td>cxx_template_template_parameters</td>
    </tr>
  </tbody>
</table>

<h6 id="compilerhas_features">compiler.has_features</h6>

<ul>
  <li>判断指定的编译器特性是否支持</li>
</ul>

<p>虽然通过<a href="detect-has-features">lib.detect.has_features</a>也能获取，但是那个接口更加底层，需要指定编译器名称。
而此接口只需要指定需要检测的特姓名称列表，就能自动切换选择当前支持的编译器，然后判断指定特性在当前的编译器中是否支持。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">if</span> <span class="n">compiler</span><span class="p">.</span><span class="n">has_features</span><span class="p">(</span><span class="s2">"c_static_assert"</span><span class="p">)</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>

<span class="k">if</span> <span class="n">compiler</span><span class="p">.</span><span class="n">has_features</span><span class="p">({</span><span class="s2">"c_static_assert"</span><span class="p">,</span> <span class="s2">"cxx_constexpr"</span><span class="p">},</span> <span class="p">{</span><span class="n">languages</span> <span class="o">=</span> <span class="s2">"cxx11"</span><span class="p">})</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>

<span class="k">if</span> <span class="n">compiler</span><span class="p">.</span><span class="n">has_features</span><span class="p">(</span><span class="s2">"cxx_constexpr"</span><span class="p">,</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">,</span> <span class="n">defines</span> <span class="o">=</span> <span class="s2">".."</span><span class="p">,</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="s2">".."</span><span class="p">})</span> <span class="k">then</span>
    <span class="c1">-- ok</span>
<span class="k">end</span>
</code></pre>
</div>

<p>具体特性名有哪些，可以参考：<a href="#compiler-features">compiler.features</a>。</p>

<h5 id="coreprojectconfig">core.project.config</h5>

<p>用于获取工程编译时候的配置信息，也就是<code class="highlighter-rouge">xmake f|config --xxx=val</code> 传入的参数选项值。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#config-get">config.get</a></td>
      <td>获取指定配置值</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-load">config.load</a></td>
      <td>加载配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-arch">config.arch</a></td>
      <td>获取当前工程的架构配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-plat">config.plat</a></td>
      <td>获取当前工程的平台配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-mode">config.mode</a></td>
      <td>获取当前工程的编译模式配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-buildir">config.buildir</a></td>
      <td>获取当前工程的输出目录配置</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-directory">config.directory</a></td>
      <td>获取当前工程的配置信息目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#config-dump">config.dump</a></td>
      <td>打印输出当前工程的所有配置信息</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="configget">config.get</h6>

<ul>
  <li>获取指定配置值</li>
</ul>

<p>用于获取<code class="highlighter-rouge">xmake f|config --xxx=val</code>的配置值，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>

        <span class="c1">-- 导入配置模块</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>

        <span class="c1">-- 获取配置值</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">config</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="configload">config.load</h6>

<ul>
  <li>加载配置</li>
</ul>

<p>一般用于插件开发中，插件任务中不像工程的自定义脚本，环境需要自己初始化加载，默认工程配置是没有被加载的，如果要用<a href="#config-get">config.get</a>接口获取工程配置，那么需要先：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code>
<span class="c1">-- 导入配置模块</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>

    <span class="c1">-- 先加载工程配置</span>
    <span class="n">config</span><span class="p">.</span><span class="n">load</span><span class="p">()</span>
    
    <span class="c1">-- 获取配置值</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">config</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"xxx"</span><span class="p">))</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="configarch">config.arch</h6>

<ul>
  <li>获取当前工程的架构配置</li>
</ul>

<p>也就是获取<code class="highlighter-rouge">xmake f|config --arch=armv7</code>的平台配置，相当于<code class="highlighter-rouge">config.get("arch")</code>。</p>

<h6 id="configplat">config.plat</h6>

<ul>
  <li>获取当前工程的平台配置</li>
</ul>

<p>也就是获取<code class="highlighter-rouge">xmake f|config --plat=iphoneos</code>的平台配置，相当于<code class="highlighter-rouge">config.get("plat")</code>。</p>

<h6 id="configmode">config.mode</h6>

<ul>
  <li>获取当前工程的编译模式配置</li>
</ul>

<p>也就是获取<code class="highlighter-rouge">xmake f|config --mode=debug</code>的平台配置，相当于<code class="highlighter-rouge">config.get("mode")</code>。</p>

<h6 id="configbuildir">config.buildir</h6>

<ul>
  <li>获取当前工程的输出目录配置</li>
</ul>

<p>也就是获取<code class="highlighter-rouge">xmake f|config -o /tmp/output</code>的平台配置，相当于<code class="highlighter-rouge">config.get("buildir")</code>。</p>

<h6 id="configdirectory">config.directory</h6>

<ul>
  <li>获取当前工程的配置信息目录</li>
</ul>

<p>获取工程配置的存储目录，默认为：<code class="highlighter-rouge">projectdir/.config</code></p>

<h6 id="configdump">config.dump</h6>

<ul>
  <li>打印输出当前工程的所有配置信息</li>
</ul>

<p>输出结果例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
    <span class="n">sh</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang++"</span>
<span class="p">,</span>   <span class="n">xcode_dir</span> <span class="o">=</span> <span class="s2">"/Applications/Xcode.app"</span>
<span class="p">,</span>   <span class="n">ar</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx ar"</span>
<span class="p">,</span>   <span class="n">small</span> <span class="o">=</span> <span class="kc">true</span>
<span class="p">,</span>   <span class="n">object</span> <span class="o">=</span> <span class="kc">false</span>
<span class="p">,</span>   <span class="n">arch</span> <span class="o">=</span> <span class="s2">"x86_64"</span>
<span class="p">,</span>   <span class="n">xcode_sdkver</span> <span class="o">=</span> <span class="s2">"10.12"</span>
<span class="p">,</span>   <span class="n">ex</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx ar"</span>
<span class="p">,</span>   <span class="n">cc</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span>
<span class="p">,</span>   <span class="n">rc</span> <span class="o">=</span> <span class="s2">"rustc"</span>
<span class="p">,</span>   <span class="n">plat</span> <span class="o">=</span> <span class="s2">"macosx"</span>
<span class="p">,</span>   <span class="n">micro</span> <span class="o">=</span> <span class="kc">false</span>
<span class="p">,</span>   <span class="n">host</span> <span class="o">=</span> <span class="s2">"macosx"</span>
<span class="p">,</span>   <span class="n">as</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span>
<span class="p">,</span>   <span class="n">dc</span> <span class="o">=</span> <span class="s2">"dmd"</span>
<span class="p">,</span>   <span class="n">gc</span> <span class="o">=</span> <span class="s2">"go"</span>
<span class="p">,</span>   <span class="n">openssl</span> <span class="o">=</span> <span class="kc">false</span>
<span class="p">,</span>   <span class="n">ccache</span> <span class="o">=</span> <span class="s2">"ccache"</span>
<span class="p">,</span>   <span class="n">cxx</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span>
<span class="p">,</span>   <span class="n">sc</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx swiftc"</span>
<span class="p">,</span>   <span class="n">mm</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span>
<span class="p">,</span>   <span class="n">buildir</span> <span class="o">=</span> <span class="s2">"build"</span>
<span class="p">,</span>   <span class="n">mxx</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang++"</span>
<span class="p">,</span>   <span class="n">ld</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang++"</span>
<span class="p">,</span>   <span class="n">mode</span> <span class="o">=</span> <span class="s2">"release"</span>
<span class="p">,</span>   <span class="n">kind</span> <span class="o">=</span> <span class="s2">"static"</span>
<span class="p">}</span>
</code></pre>
</div>

<h5 id="coreprojectglobal">core.project.global</h5>

<p class="tip">
此模块自2.1.5版本后迁移至[core.base.global](#core-base-global)。
</p>

<h5 id="coreprojecttask">core.project.task</h5>

<p class="tip">
此模块自2.1.5版本后迁移至[core.base.task](#core-base-task)。
</p>

<h5 id="coreprojectproject">core.project.project</h5>

<p>用于获取当前工程的一些描述信息，也就是在<code class="highlighter-rouge">xmake.lua</code>工程描述文件中定义的配置信息，例如：<a href="#target">target</a>、<a href="#option">option</a>等。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#project-load">project.load</a></td>
      <td>加载工程配置</td>
      <td>&gt;= 2.0.1 (2.1.5废弃)</td>
    </tr>
    <tr>
      <td><a href="#project-directory">project.directory</a></td>
      <td>获取工程目录</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#project-target">project.target</a></td>
      <td>获取指定工程目标对象</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#project-targets">project.targets</a></td>
      <td>获取工程目标对象列表</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#project-option">project.option</a></td>
      <td>获取指定的选项对象</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#project-options">project.options</a></td>
      <td>获取工程所有的选项对象</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#project-name">project.name</a></td>
      <td>获取当前工程名</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#project-version">project.version</a></td>
      <td>获取当前工程版本号</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="projectload">project.load</h6>

<ul>
  <li>加载工程描述配置</li>
</ul>

<p>仅在插件中使用，因为这个时候还没有加载工程配置信息，在工程目标的自定义脚本中，不需要执行此操作，就可以直接访问工程配置。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 导入工程模块</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.project.project"</span><span class="p">)</span>

<span class="c1">-- 插件入口</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>

    <span class="c1">-- 加载工程描述配置</span>
    <span class="n">project</span><span class="p">.</span><span class="n">load</span><span class="p">()</span>

    <span class="c1">-- 访问工程描述，例如获取指定工程目标</span>
    <span class="kd">local</span> <span class="n">target</span> <span class="o">=</span> <span class="n">project</span><span class="p">.</span><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p class="tip">
2.1.5版本后，不在需要，工程加载会自动在合适时机延迟加载。
</p>

<h6 id="projectdirectory">project.directory</h6>

<ul>
  <li>获取工程目录</li>
</ul>

<p>获取当前工程目录，也就是<code class="highlighter-rouge">xmake -P xxx</code>中指定的目录，否则为默认当前<code class="highlighter-rouge">xmake</code>命令执行目录。</p>

<p class="tip">
2.1.5版本后，建议使用[os.projectdir](#os-projectdir)来获取。
</p>

<h6 id="projecttarget">project.target</h6>

<ul>
  <li>获取指定工程目标对象</li>
</ul>

<p>获取和访问指定工程目标配置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">target</span> <span class="o">=</span> <span class="n">project</span><span class="p">.</span><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">target</span> <span class="k">then</span>

    <span class="c1">-- 获取目标文件名</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>

    <span class="c1">-- 获取目标类型，也就是：binary, static, shared</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetkind</span><span class="p">())</span>

    <span class="c1">-- 获取目标名</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">name</span><span class="p">())</span>

    <span class="c1">-- 获取目标源文件</span>
    <span class="kd">local</span> <span class="n">sourcefiles</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">sourcefiles</span><span class="p">()</span>

    <span class="c1">-- 获取目标安装头文件列表</span>
    <span class="kd">local</span> <span class="n">srcheaders</span><span class="p">,</span> <span class="n">dstheaders</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">headerfiles</span><span class="p">()</span>

    <span class="c1">-- 获取目标依赖</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">get</span><span class="p">(</span><span class="s2">"deps"</span><span class="p">))</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="projecttargets">project.targets</h6>

<ul>
  <li>获取工程目标对象列表</li>
</ul>

<p>返回当前工程的所有编译目标，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">targetname</span><span class="p">,</span> <span class="n">target</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">project</span><span class="p">.</span><span class="n">targets</span><span class="p">())</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="projectoption">project.option</h6>

<ul>
  <li>获取指定选项对象</li>
</ul>

<p>获取和访问工程中指定的选项对象，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">option</span> <span class="o">=</span> <span class="n">project</span><span class="p">.</span><span class="n">option</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">option</span><span class="p">:</span><span class="n">enabled</span><span class="p">()</span> <span class="k">then</span>
    <span class="n">option</span><span class="p">:</span><span class="n">enable</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="projectoptions">project.options</h6>

<ul>
  <li>获取工程所有选项对象</li>
</ul>

<p>返回当前工程的所有编译目标，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">for</span> <span class="n">optionname</span><span class="p">,</span> <span class="n">option</span> <span class="k">in</span> <span class="nb">pairs</span><span class="p">(</span><span class="n">project</span><span class="p">.</span><span class="n">options</span><span class="p">())</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">option</span><span class="p">:</span><span class="n">enabled</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="projectname">project.name</h6>

<ul>
  <li>获取当前工程名</li>
</ul>

<p>也就是获取<a href="#set_project">set_project</a>的工程名配置。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">project</span><span class="p">.</span><span class="n">name</span><span class="p">())</span>
</code></pre>
</div>

<h6 id="projectversion">project.version</h6>

<ul>
  <li>获取当前工程版本号</li>
</ul>

<p>也就是获取<a href="#set_version">set_version</a>的工程版本配置。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">project</span><span class="p">.</span><span class="n">version</span><span class="p">())</span>
</code></pre>
</div>

<h5 id="corelanguagelanguage">core.language.language</h5>

<p>用于获取编译语言相关信息，一般用于代码文件的操作。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#language-extensions">language.extensions</a></td>
      <td>获取所有语言的代码后缀名列表</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-targetkinds">language.targetkinds</a></td>
      <td>获取所有语言的目标类型列表</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-sourcekinds">language.sourcekinds</a></td>
      <td>获取所有语言的源文件类型列表</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-sourceflags">language.sourceflags</a></td>
      <td>加载所有语言的源文件编译选项名列表</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-load">language.load</a></td>
      <td>加载指定语言</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-load_sk">language.load_sk</a></td>
      <td>从源文件类型加载指定语言</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-load_ex">language.load_ex</a></td>
      <td>从源文件后缀名加载指定语言</td>
      <td>&gt;= 2.1.1</td>
    </tr>
    <tr>
      <td><a href="#language-sourcekind_of">language.sourcekind_of</a></td>
      <td>获取指定源文件的源文件类型</td>
      <td>&gt;= 2.1.1</td>
    </tr>
  </tbody>
</table>

<h6 id="languageextensions">language.extensions</h6>

<ul>
  <li>获取所有语言的代码后缀名列表</li>
</ul>

<p>获取结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
     <span class="p">[</span><span class="s2">".c"</span><span class="p">]</span>      <span class="o">=</span> <span class="n">cc</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".cc"</span><span class="p">]</span>     <span class="o">=</span> <span class="n">cxx</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".cpp"</span><span class="p">]</span>    <span class="o">=</span> <span class="n">cxx</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".m"</span><span class="p">]</span>      <span class="o">=</span> <span class="n">mm</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".mm"</span><span class="p">]</span>     <span class="o">=</span> <span class="n">mxx</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".swift"</span><span class="p">]</span>  <span class="o">=</span> <span class="n">sc</span>
<span class="p">,</span>    <span class="p">[</span><span class="s2">".go"</span><span class="p">]</span>     <span class="o">=</span> <span class="n">gc</span>
<span class="p">}</span>
</code></pre>
</div>

<h6 id="languagetargetkinds">language.targetkinds</h6>

<ul>
  <li>获取所有语言的目标类型列表</li>
</ul>

<p>获取结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
     <span class="n">binary</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"ld"</span><span class="p">,</span> <span class="s2">"gc-ld"</span><span class="p">,</span> <span class="s2">"dc-ld"</span><span class="p">}</span>
<span class="p">,</span>    <span class="n">static</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"ar"</span><span class="p">,</span> <span class="s2">"gc-ar"</span><span class="p">,</span> <span class="s2">"dc-ar"</span><span class="p">}</span>
<span class="p">,</span>    <span class="n">shared</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"sh"</span><span class="p">,</span> <span class="s2">"dc-sh"</span><span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<h6 id="languagesourcekinds">language.sourcekinds</h6>

<ul>
  <li>获取所有语言的源文件类型列表</li>
</ul>

<p>获取结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
     <span class="n">cc</span>  <span class="o">=</span> <span class="s2">".c"</span>
<span class="p">,</span>    <span class="n">cxx</span> <span class="o">=</span> <span class="p">{</span><span class="s2">".cc"</span><span class="p">,</span> <span class="s2">".cpp"</span><span class="p">,</span> <span class="s2">".cxx"</span><span class="p">}</span>
<span class="p">,</span>    <span class="n">mm</span>  <span class="o">=</span> <span class="s2">".m"</span>
<span class="p">,</span>    <span class="n">mxx</span> <span class="o">=</span> <span class="s2">".mm"</span>
<span class="p">,</span>    <span class="n">sc</span>  <span class="o">=</span> <span class="s2">".swift"</span>
<span class="p">,</span>    <span class="n">gc</span>  <span class="o">=</span> <span class="s2">".go"</span>
<span class="p">,</span>    <span class="n">rc</span>  <span class="o">=</span> <span class="s2">".rs"</span>
<span class="p">,</span>    <span class="n">dc</span>  <span class="o">=</span> <span class="s2">".d"</span>
<span class="p">,</span>    <span class="n">as</span>  <span class="o">=</span> <span class="p">{</span><span class="s2">".s"</span><span class="p">,</span> <span class="s2">".S"</span><span class="p">,</span> <span class="s2">".asm"</span><span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>

<h6 id="languagesourceflags">language.sourceflags</h6>

<ul>
  <li>加载所有语言的源文件编译选项名列表</li>
</ul>

<p>获取结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
     <span class="n">cc</span>  <span class="o">=</span> <span class="p">{</span><span class="s2">"cflags"</span><span class="p">,</span> <span class="s2">"cxflags"</span><span class="p">}</span>
<span class="p">,</span>    <span class="n">cxx</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"cxxflags"</span><span class="p">,</span> <span class="s2">"cxflags"</span><span class="p">}</span>
<span class="p">,</span>    <span class="o">...</span>
<span class="p">}</span>
</code></pre>
</div>

<h6 id="languageload">language.load</h6>

<ul>
  <li>加载指定语言</li>
</ul>

<p>从语言名称加载具体语言对象，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">lang</span> <span class="o">=</span> <span class="n">language</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="s2">"c++"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lang</span> <span class="k">then</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">lang</span><span class="p">:</span><span class="n">name</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="languageload_sk">language.load_sk</h6>

<ul>
  <li>从源文件类型加载指定语言</li>
</ul>

<p>从源文件类型：<code class="highlighter-rouge">cc, cxx, mm, mxx, sc, gc, as ..</code>加载具体语言对象，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">lang</span> <span class="o">=</span> <span class="n">language</span><span class="p">.</span><span class="n">load_sk</span><span class="p">(</span><span class="s2">"cxx"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lang</span> <span class="k">then</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">lang</span><span class="p">:</span><span class="n">name</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="languageload_ex">language.load_ex</h6>

<ul>
  <li>从源文件后缀名加载指定语言</li>
</ul>

<p>从源文件后缀名：<code class="highlighter-rouge">.cc, .c, .cpp, .mm, .swift, .go  ..</code>加载具体语言对象，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">lang</span> <span class="o">=</span> <span class="n">language</span><span class="p">.</span><span class="n">load_sk</span><span class="p">(</span><span class="s2">".cpp"</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lang</span> <span class="k">then</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">lang</span><span class="p">:</span><span class="n">name</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="languagesourcekind_of">language.sourcekind_of</h6>

<ul>
  <li>获取指定源文件的源文件类型</li>
</ul>

<p>也就是从给定的一个源文件路径，获取它是属于那种源文件类型，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">language</span><span class="p">.</span><span class="n">sourcekind_of</span><span class="p">(</span><span class="s2">"/xxxx/test.cpp"</span><span class="p">))</span>
</code></pre>
</div>

<p>显示结果为：<code class="highlighter-rouge">cxx</code>，也就是<code class="highlighter-rouge">c++</code>类型，具体对应列表见：<a href="#language-sourcekinds">language.sourcekinds</a></p>

<h5 id="coreplatformplatform">core.platform.platform</h5>

<p>平台信息相关操作</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#platform-get">platform.get</a></td>
      <td>获取指定平台相关配置信息</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="platformget">platform.get</h6>

<ul>
  <li>获取指定平台相关配置信息</li>
</ul>

<p>获取平台配置<code class="highlighter-rouge">xmake.lua</code>中设置的信息，一般只有在写插件的时候会用到，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 获取当前平台的所有支持架构</span>
<span class="nb">print</span><span class="p">(</span><span class="n">platform</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"archs"</span><span class="p">))</span>

<span class="c1">-- 获取指定iphoneos平台的目标文件格式信息</span>
<span class="kd">local</span> <span class="n">formats</span> <span class="o">=</span> <span class="n">platform</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"formats"</span><span class="p">,</span> <span class="s2">"iphoneos"</span><span class="p">)</span>
<span class="n">table</span><span class="p">.</span><span class="n">dump</span><span class="p">(</span><span class="n">formats</span><span class="p">)</span>
</code></pre>
</div>

<p>具体有哪些可读的平台配置信息，可参考：<a href="#platform">platform</a></p>

<h5 id="coreplatformenvironment">core.platform.environment</h5>

<p>环境相关操作，用于进入和离开指定环境变量对应的终端环境，一般用于<code class="highlighter-rouge">path</code>环境的进入和离开，尤其是一些需要特定环境的构建工具，例如：msvc的工具链。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#environment-enter">environment.enter</a></td>
      <td>进入指定环境</td>
      <td>&gt;= 2.0.1</td>
    </tr>
    <tr>
      <td><a href="#environment-leave">environment.leave</a></td>
      <td>离开指定环境</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<p>目前支持的环境有：</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>toolchains</td>
      <td>工具链执行环境</td>
      <td>&gt;= 2.0.1</td>
    </tr>
  </tbody>
</table>

<h6 id="environmententer">environment.enter</h6>

<ul>
  <li>进入指定环境</li>
</ul>

<p>进入指定环境，例如msvc有自己的环境变量环境用于运行构建工具，例如：<code class="highlighter-rouge">cl.exe</code>, <code class="highlighter-rouge">link.exe</code>这些，这个时候想要在xmake里面运行他们，需要：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 进入工具链环境</span>
<span class="n">environment</span><span class="p">.</span><span class="n">enter</span><span class="p">(</span><span class="s2">"toolchains"</span><span class="p">)</span>

<span class="c1">-- 这个时候运行cl.exe才能正常运行，这个时候的path等环境变量都会进入msvc的环境模式</span>
<span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"cl.exe .."</span><span class="p">)</span>

<span class="c1">-- 离开工具链环境</span>
<span class="n">environment</span><span class="p">.</span><span class="n">leave</span><span class="p">(</span><span class="s2">"toolchains"</span><span class="p">)</span>
</code></pre>
</div>

<p>因此为了通用性，默认xmake编译事都会设置这个环境，在linux下基本上内部环境不需要特殊切换，目前仅对windows下msvc进行了处理。</p>

<h6 id="environmentleave">environment.leave</h6>

<ul>
  <li>离开指定环境</li>
</ul>

<p>具体使用见：<a href="#environment-enter">environment.enter</a></p>

<h5 id="libdetect">lib.detect</h5>

<p>此模块提供了非常强大的探测功能，用于探测程序、编译器、语言特性、依赖包等。</p>

<p class="tip">
此模块的接口分散在多个模块目录中，尽量通过导入单个接口来使用，这样效率更高，例如：`import("lib.detect.find_package")`，而不是通过`import("lib.detect")`导入所有来调用。
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#detect-find_file">detect.find_file</a></td>
      <td>查找文件</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_path">detect.find_path</a></td>
      <td>查找文件路径</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_library">detect.find_library</a></td>
      <td>查找库文件</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_program">detect.find_program</a></td>
      <td>查找可执行程序</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_programver">detect.find_programver</a></td>
      <td>查找可执行程序版本号</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_package">detect.find_package</a></td>
      <td>查找包文件，包含库文件和搜索路径</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_tool">detect.find_tool</a></td>
      <td>查找工具</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-find_toolname">detect.find_toolname</a></td>
      <td>查找工具名</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-features">detect.features</a></td>
      <td>获取指定工具的所有特性</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_features">detect.has_features</a></td>
      <td>判断指定特性是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_flags">detect.has_flags</a></td>
      <td>判断指定参数选项是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_cfuncs">detect.has_cfuncs</a></td>
      <td>判断指定c函数是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_cxxfuncs">detect.has_cxxfuncs</a></td>
      <td>判断指定c++函数是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_cincludes">detect.has_cincludes</a></td>
      <td>判断指定c头文件是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_cxxincludes">detect.has_cxxincludess</a></td>
      <td>判断指定c++头文件是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_ctypes">detect.has_ctypes</a></td>
      <td>判断指定c类型是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-has_cxxtypes">detect.has_cxxtypes</a></td>
      <td>判断指定c++类型是否存在</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#detect-check_cxsnippets">detect.check_cxsnippets</a></td>
      <td>检测c/c++代码片段是否能够编译通过</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="detectfind_file">detect.find_file</h6>

<ul>
  <li>查找文件</li>
</ul>

<p>这个接口提供了比<a href="#os-files">os.files</a>更加强大的工程， 可以同时指定多个搜索目录，并且还能对每个目录指定附加的子目录，来模式匹配查找，相当于是<a href="#os-files">os.files</a>的增强版。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_file"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="n">find_file</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">})</span>
</code></pre>
</div>

<p>如果找到，返回的结果是：<code class="highlighter-rouge">/usr/bin/ccache</code></p>

<p>它同时也支持模式匹配路径，进行递归查找，类似<code class="highlighter-rouge">os.files</code>：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="n">find_file</span><span class="p">(</span><span class="s2">"test.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"/usr/include"</span><span class="p">,</span> <span class="s2">"/usr/local/include/**"</span><span class="p">})</span>
</code></pre>
</div>

<p>不仅如此，里面的路径也支持内建变量，来从环境变量和注册表中获取路径进行查找：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="n">find_file</span><span class="p">(</span><span class="s2">"xxx.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="s2">"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"</span><span class="p">})</span>
</code></pre>
</div>

<p>如果路径规则比较复杂多变，还可以通过自定义脚本来动态生成路径传入：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="n">find_file</span><span class="p">(</span><span class="s2">"xxx.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="k">return</span> <span class="n">val</span><span class="p">(</span><span class="s2">"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"</span><span class="p">):</span><span class="n">match</span><span class="p">(</span><span class="s2">"</span><span class="se">\"</span><span class="s2">(.-)\"") end})
</span></code></pre>
</div>

<p>大部分场合下，上面的使用已经满足各种需求了，如果还需要一些扩展功能，可以通过传入第三个参数，自定义一些可选配置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">file</span> <span class="o">=</span> <span class="n">find_file</span><span class="p">(</span><span class="s2">"test.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"/usr"</span><span class="p">,</span> <span class="s2">"/usr/local"</span><span class="p">},</span> <span class="p">{</span><span class="n">suffixes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/include"</span><span class="p">,</span> <span class="s2">"/lib"</span><span class="p">}})</span>
</code></pre>
</div>

<p>通过指定suffixes子目录列表，可以扩展路径列表（第二个参数），使得实际的搜索目录扩展为：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>/usr/include
/usr/lib
/usr/local/include
/usr/local/lib
</code></pre>
</div>

<p>并且不用改变路径列表，就能动态切换子目录来搜索文件。</p>

<p class="tip">
我们也可以通过`xmake lua`插件来快速调用和测试此接口：`xmake lua lib.detect.find_file test.h /usr/local`
</p>

<h6 id="detectfind_path">detect.find_path</h6>

<ul>
  <li>查找路径</li>
</ul>

<p>这个接口的用法跟<a href="#detect-find_file">lib.detect.find_file</a>类似，唯一的区别是返回的结果不同。
此接口查找到传入的文件路径后，返回的是对应的搜索路径，而不是文件路径本身，一般用于查找文件对应的父目录位置。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_path"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">p</span> <span class="o">=</span> <span class="n">find_path</span><span class="p">(</span><span class="s2">"include/test.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"/usr"</span><span class="p">,</span> <span class="s2">"/usr/local"</span><span class="p">})</span>
</code></pre>
</div>

<p>上述代码如果查找成功，则返回：<code class="highlighter-rouge">/usr/local</code>，如果<code class="highlighter-rouge">test.h</code>在<code class="highlighter-rouge">/usr/local/include/test.h</code>的话。</p>

<p>还有一个区别就是，这个接口传入不只是文件路径，还可以传入目录路径来查找：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">p</span> <span class="o">=</span> <span class="n">find_path</span><span class="p">(</span><span class="s2">"lib/xxx"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="s2">"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"</span><span class="p">})</span>
</code></pre>
</div>

<p>同样，此接口也支持模式匹配和后缀子目录：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">p</span> <span class="o">=</span> <span class="n">find_path</span><span class="p">(</span><span class="s2">"include/*.h"</span><span class="p">,</span> <span class="p">{</span> <span class="s2">"/usr"</span><span class="p">,</span> <span class="s2">"/usr/local/**"</span><span class="p">},</span> <span class="p">{</span><span class="n">suffixes</span> <span class="o">=</span> <span class="s2">"/subdir"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="detectfind_library">detect.find_library</h6>

<ul>
  <li>查找库文件</li>
</ul>

<p>此接口用于指定的搜索目录中查找库文件（静态库，动态库），例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_library"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">library</span> <span class="o">=</span> <span class="n">find_library</span><span class="p">(</span><span class="s2">"crypto"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"/usr/lib"</span><span class="p">,</span> <span class="s2">"/usr/local/lib"</span><span class="p">})</span>
</code></pre>
</div>

<p>在macosx上运行，返回的结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">libcrypto</span><span class="p">.</span><span class="n">dylib</span>
<span class="p">,</span>   <span class="n">linkdir</span> <span class="o">=</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span>
<span class="p">,</span>   <span class="n">link</span> <span class="o">=</span> <span class="n">crypto</span>
<span class="p">,</span>   <span class="n">kind</span> <span class="o">=</span> <span class="n">shared</span>
<span class="p">}</span>
</code></pre>
</div>

<p>如果不指定是否需要静态库还是动态库，那么此接口会自动选择一个存在的库（有可能是静态库、也有可能是动态库）进行返回。</p>

<p>如果需要强制指定需要查找的库类型，可以指定kind参数为（<code class="highlighter-rouge">static/shared</code>）：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">library</span> <span class="o">=</span> <span class="n">find_library</span><span class="p">(</span><span class="s2">"crypto"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"/usr/lib"</span><span class="p">,</span> <span class="s2">"/usr/local/lib"</span><span class="p">},</span> <span class="p">{</span><span class="n">kind</span> <span class="o">=</span> <span class="s2">"static"</span><span class="p">})</span>
</code></pre>
</div>

<p>此接口也支持suffixes后缀子目录搜索和模式匹配操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">library</span> <span class="o">=</span> <span class="n">find_library</span><span class="p">(</span><span class="s2">"cryp*"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"/usr"</span><span class="p">,</span> <span class="s2">"/usr/local"</span><span class="p">},</span> <span class="p">{</span><span class="n">suffixes</span> <span class="o">=</span> <span class="s2">"/lib"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="detectfind_program">detect.find_program</h6>

<ul>
  <li>查找可执行程序</li>
</ul>

<p>这个接口比<a href="#detect-find_tool">lib.detect.find_tool</a>较为原始底层，通过指定的参数目录来查找可执行程序。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_program"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">)</span>
</code></pre>
</div>

<p>上述代码犹如没有传递搜索目录，所以它会尝试直接执行指定程序，如果运行ok，那么直接返回：<code class="highlighter-rouge">ccache</code>，表示查找成功。</p>

<p>指定搜索目录，修改尝试运行的检测命令参数（默认是：<code class="highlighter-rouge">ccache --version</code>）：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">},</span> <span class="n">check</span> <span class="o">=</span> <span class="s2">"--help"</span><span class="p">})</span> 
</code></pre>
</div>

<p>上述代码会尝试运行：<code class="highlighter-rouge">/usr/bin/ccache --help</code>，如果运行成功，则返回：<code class="highlighter-rouge">/usr/bin/ccache</code>。</p>

<p>如果<code class="highlighter-rouge">--help</code>也没法满足需求，有些程序没有<code class="highlighter-rouge">--version/--help</code>参数，那么可以自定义运行脚本，来运行检测：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">},</span> <span class="n">check</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="n">program</span><span class="p">)</span> <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"%s -h"</span><span class="p">,</span> <span class="n">program</span><span class="p">)</span> <span class="k">end</span><span class="p">})</span>
</code></pre>
</div>

<p>同样，搜索路径列表支持内建变量和自定义脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="s2">"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"</span><span class="p">}})</span>
<span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="k">return</span> <span class="s2">"/usr/local/bin"</span> <span class="k">end</span><span class="p">}})</span>
</code></pre>
</div>

<p class="tip">
为了加速频发查找的效率，此接口是默认自带cache的，所以就算频繁查找相同的程序，也不会花太多时间。
如果要禁用cache，可以在工程目录执行`xmake f -c`清除本地cache。
</p>

<p>我们也可以通过<code class="highlighter-rouge">xmake lua lib.detect.find_program ccache</code> 来快速测试。</p>

<h6 id="detectfind_programver">detect.find_programver</h6>

<ul>
  <li>查找可执行程序版本号</li>
</ul>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_programver"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">programver</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">)</span>
</code></pre>
</div>

<p>返回结果为：3.2.2</p>

<p>默认它会通过<code class="highlighter-rouge">ccache --version</code>尝试获取版本，如果不存在此参数，可以自己指定其他参数：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">version</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">command</span> <span class="o">=</span> <span class="s2">"-v"</span><span class="p">})</span>
</code></pre>
</div>

<p>甚至自定义版本获取脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">version</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">command</span> <span class="o">=</span> <span class="k">function</span> <span class="p">()</span> <span class="k">return</span> <span class="n">os</span><span class="p">.</span><span class="n">iorun</span><span class="p">(</span><span class="s2">"ccache --version"</span><span class="p">)</span> <span class="k">end</span><span class="p">})</span>
</code></pre>
</div>

<p>对于版本号的提取规则，如果内置的匹配模式不满足要求，也可以自定义：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">version</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">command</span> <span class="o">=</span> <span class="s2">"--version"</span><span class="p">,</span> <span class="n">parse</span> <span class="o">=</span> <span class="s2">"(%d+%.?%d*%.?%d*.-)%s"</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">version</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="s2">"ccache"</span><span class="p">,</span> <span class="p">{</span><span class="n">command</span> <span class="o">=</span> <span class="s2">"--version"</span><span class="p">,</span> <span class="n">parse</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="n">output</span><span class="p">)</span> <span class="k">return</span> <span class="n">output</span><span class="p">:</span><span class="n">match</span><span class="p">(</span><span class="s2">"(%d+%.?%d*%.?%d*.-)%s"</span><span class="p">)</span> <span class="k">end</span><span class="p">})</span>
</code></pre>
</div>

<p class="tip">
为了加速频发查找的效率，此接口是默认自带cache的，如果要禁用cache，可以在工程目录执行`xmake f -c`清除本地cache。
</p>

<p>我们也可以通过<code class="highlighter-rouge">xmake lua lib.detect.find_programver ccache</code> 来快速测试。</p>

<h6 id="detectfind_package">detect.find_package</h6>

<ul>
  <li>查找包文件</li>
</ul>

<p>此接口也是用于查找库文件，但是比<a href="#detect-find_library">lib.detect.find_library</a>更加上层，也更为强大和简单易用，因为它是以包为力度进行查找。</p>

<p>那怎样算是一个完整的包，它包含：</p>

<ol>
  <li>多个静态库或者动态库文件</li>
  <li>库的搜索目录</li>
  <li>头文件的搜索目录</li>
  <li>可选的编译链接选项，例如：<code class="highlighter-rouge">defines</code>等</li>
  <li>可选的版本号</li>
</ol>

<p>例如我们查找一个openssl包：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_package"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">package</span> <span class="o">=</span> <span class="n">find_package</span><span class="p">(</span><span class="s2">"openssl"</span><span class="p">)</span>
</code></pre>
</div>

<p>返回的结果如下：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span><span class="n">links</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"ssl"</span><span class="p">,</span> <span class="s2">"crypto"</span><span class="p">,</span> <span class="s2">"z"</span><span class="p">},</span> <span class="n">linkdirs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/local/lib"</span><span class="p">},</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/local/include"</span><span class="p">}}</span>
</code></pre>
</div>

<p>如果查找成功，则返回一个包含所有包信息的table，如果失败返回nil</p>

<p>这里的返回结果可以直接作为<code class="highlighter-rouge">target:add</code>, <code class="highlighter-rouge">option:add</code>的参数传入，用于动态增加<code class="highlighter-rouge">target/option</code>的配置：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">option</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">)</span>
    <span class="n">set_showmenu</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="n">before_check</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">option</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_package"</span><span class="p">)</span>
        <span class="n">option</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="n">find_package</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_package"</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="n">find_package</span><span class="p">(</span><span class="s2">"zlib"</span><span class="p">))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>如果系统上装有<code class="highlighter-rouge">homebrew</code>, <code class="highlighter-rouge">pkg-config</code>等第三方工具，那么此接口会尝试使用它们去改进查找结果。</p>

<p>我们也可以通过指定版本号，来选择查找指定版本的包（如果这个包获取不到版本信息或者没有匹配版本的包，则返回nil）：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">package</span> <span class="o">=</span> <span class="n">find_package</span><span class="p">(</span><span class="s2">"openssl"</span><span class="p">,</span> <span class="p">{</span><span class="n">version</span> <span class="o">=</span> <span class="s2">"1.0.1"</span><span class="p">})</span>
</code></pre>
</div>

<p>默认情况下查找的包是根据如下规则匹配平台，架构和模式的：</p>

<ol>
  <li>如果参数传入指定了<code class="highlighter-rouge"><span class="p">{</span><span class="err">plat</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"iphoneos"</span><span class="err">,</span><span class="w"> </span><span class="err">arch</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"arm64"</span><span class="err">,</span><span class="w"> </span><span class="err">mode</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"release"</span><span class="err">}</span></code>，则优先匹配，例如：<code class="highlighter-rouge">find_package("openssl", {plat = "iphoneos"})</code>。</li>
  <li>如果是在当前工程环境，存在配置文件，则优先尝试从<code class="highlighter-rouge">config.get("plat")</code>, <code class="highlighter-rouge">config.get("arch")</code>和<code class="highlighter-rouge">config.get("mode")</code>获取平台架构进行匹配。</li>
  <li>最后从<code class="highlighter-rouge">os.host()</code>和<code class="highlighter-rouge">os.arch()</code>中进行匹配，也就是当前主机的平台架构环境。</li>
</ol>

<p>如果系统的库目录以及<code class="highlighter-rouge">pkg-config</code>都不能满足需求，找不到包，那么可以自己手动设置搜索路径：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">package</span> <span class="o">=</span> <span class="n">find_package</span><span class="p">(</span><span class="s2">"openssl"</span><span class="p">,</span> <span class="p">{</span><span class="n">linkdirs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/lib"</span><span class="p">,</span> <span class="s2">"/usr/local/lib"</span><span class="p">},</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="s2">"/usr/local/include"</span><span class="p">})</span>
</code></pre>
</div>

<p>也可以同时指定需要搜索的链接名，头文件名：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">package</span> <span class="o">=</span> <span class="n">find_package</span><span class="p">(</span><span class="s2">"openssl"</span><span class="p">,</span> <span class="p">{</span><span class="n">links</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"ssl"</span><span class="p">,</span> <span class="s2">"crypto"</span><span class="p">},</span> <span class="n">includes</span> <span class="o">=</span> <span class="s2">"ssl.h"</span><span class="p">}})</span>
</code></pre>
</div>

<p>甚至可以指定xmake的<code class="highlighter-rouge">packagedir/*.pkg</code>包目录，用于查找对应的<code class="highlighter-rouge">openssl.pkg</code>包，一般用于查找内置在工程目录中的本地包。</p>

<p>例如，tbox工程内置了<code class="highlighter-rouge">pkg/openssl.pkg</code>本地包载项目中，我们可以通过下面的脚本，传入<code class="highlighter-rouge"><span class="p">{</span><span class="err">packagedirs</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">""</span><span class="err">}</span></code>参数优先查找本地包，如果找不到再去找系统包。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_package"</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="n">find_package</span><span class="p">(</span><span class="s2">"openssl"</span><span class="p">,</span> <span class="p">{</span><span class="n">packagedirs</span> <span class="o">=</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">projectdir</span><span class="p">(),</span> <span class="s2">"pkg"</span><span class="p">)}))</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>总结下，现在的查找顺序：</p>

<ol>
  <li>如果指定<code class="highlighter-rouge"><span class="p">{</span><span class="err">packagedirs</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">""</span><span class="err">}</span></code>参数，优先从这个参数指定的路径中查找本地包<code class="highlighter-rouge">*.pkg</code></li>
  <li>如果在<code class="highlighter-rouge">xmake/modules</code>下面存在<code class="highlighter-rouge">detect.packages.find_xxx</code>脚本，那么尝试调用此脚本来改进查找结果</li>
  <li>如果系统存在<code class="highlighter-rouge">pkg-config</code>，并且查找的是系统环境的库，则尝试使用<code class="highlighter-rouge">pkg-config</code>提供的路径和链接信息进行查找</li>
  <li>如果系统存在<code class="highlighter-rouge">homebrew</code>，并且查找的是系统环境的库，则尝试使用<code class="highlighter-rouge">brew --prefix xxx</code>提供的信息进行查找</li>
  <li>从参数中指定的pathes路径和一些已知的系统路径<code class="highlighter-rouge">/usr/lib</code>, <code class="highlighter-rouge">/usr/include</code>中进行查找</li>
</ol>

<p>这里需要着重说下第二点，通过在<code class="highlighter-rouge">detect.packages.find_xxx</code>脚本来改进查找结果，很多时候自动的包探测是没法完全探测到包路径的，
尤其是针对windows平台，没有默认的库目录，也没有包管理app，很多库装的时候，都是自己所处放置在系统目录，或者添加注册表项。</p>

<p>因此查找起来没有同意的规则，这个时候，就可以自定义一个查找脚本，去改进<code class="highlighter-rouge">find_package</code>的查找机制，对指定包进行更精准的查找。</p>

<p>在xmake自带的<code class="highlighter-rouge">xmake/modules/detect/packages</code>目录下，已经有许多的内置包脚本，来对常用的包进行更好的查找支持。
当然这不可能满足所有用户的需求，如果用户需要的包还是找不到，那么可以自己定义一个查找脚本，例如：</p>

<p>查找一个名为<code class="highlighter-rouge">openssl</code>的包，可以编写一个<code class="highlighter-rouge">find_openssl.lua</code>的脚本放置在工程目录：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>projectdir
 - xmake
   - modules
     - detect/package/find_openssl.lua
</code></pre>
</div>

<p>然后在工程的<code class="highlighter-rouge">xmake.lua</code>文件的开头指定下这个modules的目录：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">add_moduledirs</span><span class="p">(</span><span class="s2">"$(projectdir)/xmake/modules"</span><span class="p">)</span>
</code></pre>
</div>

<p>这样xmake就能找到自定义的扩展模块了。</p>

<p>接下来我们看下<code class="highlighter-rouge">find_openssl.lua</code>的实现：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- imports</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_path"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_library"</span><span class="p">)</span>

<span class="c1">-- find openssl </span>
<span class="c1">--</span>
<span class="c1">-- @param opt   the package options. e.g. see the options of find_package()</span>
<span class="c1">--</span>
<span class="c1">-- @return      see the return value of find_package()</span>
<span class="c1">--</span>
<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span>

    <span class="c1">-- for windows platform</span>
    <span class="c1">--</span>
    <span class="c1">-- http://www.slproweb.com/products/Win32OpenSSL.html</span>
    <span class="c1">--</span>
    <span class="k">if</span> <span class="n">opt</span><span class="p">.</span><span class="n">plat</span> <span class="o">==</span> <span class="s2">"windows"</span> <span class="k">then</span>

        <span class="c1">-- init bits</span>
        <span class="kd">local</span> <span class="n">bits</span> <span class="o">=</span> <span class="n">ifelse</span><span class="p">(</span><span class="n">opt</span><span class="p">.</span><span class="n">arch</span> <span class="o">==</span> <span class="s2">"x64"</span><span class="p">,</span> <span class="s2">"64"</span><span class="p">,</span> <span class="s2">"32"</span><span class="p">)</span>

        <span class="c1">-- init search pathes</span>
        <span class="kd">local</span> <span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL %("</span> <span class="o">..</span> <span class="n">bits</span> <span class="o">..</span> <span class="s2">"-bit%)_is1;Inno Setup: App Path)"</span><span class="p">,</span>
                        <span class="s2">"$(env PROGRAMFILES)/OpenSSL"</span><span class="p">,</span>
                        <span class="s2">"$(env PROGRAMFILES)/OpenSSL-Win"</span> <span class="o">..</span> <span class="n">bits</span><span class="p">,</span>
                        <span class="s2">"C:/OpenSSL"</span><span class="p">,</span>
                        <span class="s2">"C:/OpenSSL-Win"</span> <span class="o">..</span> <span class="n">bits</span><span class="p">}</span>

        <span class="c1">-- find library</span>
        <span class="kd">local</span> <span class="n">result</span> <span class="o">=</span> <span class="p">{</span><span class="n">links</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">linkdirs</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">includedirs</span> <span class="o">=</span> <span class="p">{}}</span>
        <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">name</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"libssl"</span><span class="p">,</span> <span class="s2">"libcrypto"</span><span class="p">})</span> <span class="k">do</span>
            <span class="kd">local</span> <span class="n">linkinfo</span> <span class="o">=</span> <span class="n">find_library</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">pathes</span><span class="p">,</span> <span class="p">{</span><span class="n">suffixes</span> <span class="o">=</span> <span class="s2">"lib"</span><span class="p">})</span>
            <span class="k">if</span> <span class="n">linkinfo</span> <span class="k">then</span>
                <span class="nb">table.insert</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">links</span><span class="p">,</span> <span class="n">linkinfo</span><span class="p">.</span><span class="n">link</span><span class="p">)</span>
                <span class="nb">table.insert</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">linkdirs</span><span class="p">,</span> <span class="n">linkinfo</span><span class="p">.</span><span class="n">linkdir</span><span class="p">)</span>
            <span class="k">end</span>
        <span class="k">end</span>

        <span class="c1">-- not found?</span>
        <span class="k">if</span> <span class="o">#</span><span class="n">result</span><span class="p">.</span><span class="n">links</span> <span class="o">~=</span> <span class="mi">2</span> <span class="k">then</span>
            <span class="k">return</span> 
        <span class="k">end</span>

        <span class="c1">-- find include</span>
        <span class="nb">table.insert</span><span class="p">(</span><span class="n">result</span><span class="p">.</span><span class="n">includedirs</span><span class="p">,</span> <span class="n">find_path</span><span class="p">(</span><span class="s2">"openssl/ssl.h"</span><span class="p">,</span> <span class="n">pathes</span><span class="p">,</span> <span class="p">{</span><span class="n">suffixes</span> <span class="o">=</span> <span class="s2">"include"</span><span class="p">}))</span>

        <span class="c1">-- ok</span>
        <span class="k">return</span> <span class="n">result</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>

<p>里面对windows平台进行注册表读取，去查找指定的库文件，其底层其实也是调用的<a href="#detect-find_library">find_library</a>等接口。</p>

<p class="tip">
为了加速频发查找的效率，此接口是默认自带cache的，如果要禁用cache，可以在工程目录执行`xmake f -c`清除本地cache。
也可以通过指定force参数，来禁用cache，强制重新查找：`find_package("openssl", {force = true})`
</p>

<p>我们也可以通过<code class="highlighter-rouge">xmake lua lib.detect.find_package openssl</code> 来快速测试。</p>

<h6 id="detectfind_tool">detect.find_tool</h6>

<ul>
  <li>查找工具</li>
</ul>

<p>此接口也是用于查找可执行程序，不过比<a href="#detect-find_program">lib.detect.find_program</a>更加的高级，功能也更加强大，它对可执行程序进行了封装，提供了工具这个概念：</p>

<ul>
  <li>toolname: 工具名，可执行程序的简称，用于标示某个工具，例如：<code class="highlighter-rouge">gcc</code>, <code class="highlighter-rouge">clang</code>等</li>
  <li>program: 可执行程序命令，例如：<code class="highlighter-rouge">xcrun -sdk macosx clang</code></li>
</ul>

<p>其对应关系如下：</p>

<table>
  <thead>
    <tr>
      <th>toolname</th>
      <th>program</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>clang</td>
      <td><code class="highlighter-rouge">xcrun -sdk macosx clang</code></td>
    </tr>
    <tr>
      <td>gcc</td>
      <td><code class="highlighter-rouge">/usr/toolchains/bin/arm-linux-gcc</code></td>
    </tr>
    <tr>
      <td>link</td>
      <td><code class="highlighter-rouge">link.exe -lib</code></td>
    </tr>
  </tbody>
</table>

<p><a href="#detect-find_program">lib.detect.find_program</a>只能通过传入的原始program命令或路径，去判断该程序是否存在。
而<code class="highlighter-rouge">find_tool</code>则可以通过更加一致的toolname去查找工具，并且返回对应的program完整命令路径，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_tool"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">)</span>
</code></pre>
</div>

<p>返回的结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">name</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"clang"</span><span class="err">,</span><span class="w"> </span><span class="err">program</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"clang"</span><span class="err">}</span></code>，这个时候还看不出区别，我们可以手动指定可执行的命令：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">program</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span><span class="p">})</span>
</code></pre>
</div>

<p>返回的结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">name</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"clang"</span><span class="err">,</span><span class="w"> </span><span class="err">program</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"xcrun -sdk macosx clang"</span><span class="err">}</span></code></p>

<p>而在macosx下，gcc就是clang，如果我们执行<code class="highlighter-rouge">gcc --version</code>可以看到就是clang的一个马甲，我们可以通过<code class="highlighter-rouge">find_tool</code>接口进行智能识别：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"gcc"</span><span class="p">)</span>
</code></pre>
</div>

<p>返回的结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">name</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"clang"</span><span class="err">,</span><span class="w"> </span><span class="err">program</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"gcc"</span><span class="err">}</span></code></p>

<p>通过这个结果就可以看的区别来了，工具名实际会被标示为clang，但是可执行的命令用的是gcc。</p>

<p>我们也可以指定<code class="highlighter-rouge"><span class="p">{</span><span class="err">version</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="err">true</span><span class="p">}</span></code>参数去获取工具的版本，并且指定一个自定义的搜索路径，也支持内建变量和自定义脚本哦：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">version</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="p">{</span><span class="n">pathes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"/usr/bin"</span><span class="p">,</span> <span class="s2">"/usr/local/bin"</span><span class="p">,</span> <span class="s2">"$(env PATH)"</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="k">return</span> <span class="s2">"/usr/xxx/bin"</span> <span class="k">end</span><span class="p">}})</span>
</code></pre>
</div>

<p>返回的结果为：<code class="highlighter-rouge"><span class="p">{</span><span class="err">name</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"clang"</span><span class="err">,</span><span class="w"> </span><span class="err">program</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"/usr/bin/clang"</span><span class="err">,</span><span class="w"> </span><span class="err">version</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"4.0"</span><span class="err">}</span></code></p>

<p>这个接口是对<code class="highlighter-rouge">find_program</code>的上层封装，因此也支持自定义脚本检测：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">check</span> <span class="o">=</span> <span class="s2">"--help"</span><span class="p">})</span> 
<span class="kd">local</span> <span class="n">tool</span> <span class="o">=</span> <span class="n">find_tool</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">check</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="n">tool</span><span class="p">)</span> <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"%s -h"</span><span class="p">,</span> <span class="n">tool</span><span class="p">)</span> <span class="k">end</span><span class="p">})</span>
</code></pre>
</div>

<p>最后总结下，<code class="highlighter-rouge">find_tool</code>的查找流程：</p>

<ol>
  <li>优先通过<code class="highlighter-rouge"><span class="p">{</span><span class="err">program</span><span class="w"> </span><span class="err">=</span><span class="w"> </span><span class="nt">"xxx"</span><span class="err">}</span></code>的参数来尝试运行和检测。</li>
  <li>如果在<code class="highlighter-rouge">xmake/modules/detect/tools</code>下存在<code class="highlighter-rouge">detect.tools.find_xxx</code>脚本，则调用此脚本进行更加精准的检测。</li>
  <li>尝试从<code class="highlighter-rouge">/usr/bin</code>，<code class="highlighter-rouge">/usr/local/bin</code>等系统目录进行检测。</li>
</ol>

<p>我们也可以在工程<code class="highlighter-rouge">xmake.lua</code>中<code class="highlighter-rouge">add_moduledirs</code>指定的模块目录中，添加自定义查找脚本，来改进检测机制：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>projectdir
  - xmake/modules
    - detect/tools/find_xxx.lua
</code></pre>
</div>

<p>例如我们自定义一个<code class="highlighter-rouge">find_7z.lua</code>的查找脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_program"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.find_programver"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="n">opt</span><span class="p">)</span>

    <span class="c1">-- init options</span>
    <span class="n">opt</span> <span class="o">=</span> <span class="n">opt</span> <span class="ow">or</span> <span class="p">{}</span>

    <span class="c1">-- find program</span>
    <span class="kd">local</span> <span class="n">program</span> <span class="o">=</span> <span class="n">find_program</span><span class="p">(</span><span class="n">opt</span><span class="p">.</span><span class="n">program</span> <span class="ow">or</span> <span class="s2">"7z"</span><span class="p">,</span> <span class="n">opt</span><span class="p">.</span><span class="n">pathes</span><span class="p">,</span> <span class="n">opt</span><span class="p">.</span><span class="n">check</span> <span class="ow">or</span> <span class="s2">"--help"</span><span class="p">)</span>

    <span class="c1">-- find program version</span>
    <span class="kd">local</span> <span class="n">version</span> <span class="o">=</span> <span class="kc">nil</span>
    <span class="k">if</span> <span class="n">program</span> <span class="ow">and</span> <span class="n">opt</span> <span class="ow">and</span> <span class="n">opt</span><span class="p">.</span><span class="n">version</span> <span class="k">then</span>
        <span class="n">version</span> <span class="o">=</span> <span class="n">find_programver</span><span class="p">(</span><span class="n">program</span><span class="p">,</span> <span class="s2">"--help"</span><span class="p">,</span> <span class="s2">"(%d+%.?%d*)%s"</span><span class="p">)</span>
    <span class="k">end</span>

    <span class="c1">-- ok?</span>
    <span class="k">return</span> <span class="n">program</span><span class="p">,</span> <span class="n">version</span>
<span class="k">end</span>
</code></pre>
</div>

<p>将它放置到工程的模块目录下后，执行：<code class="highlighter-rouge">xmake l lib.detect.find_tool 7z</code>就可以查找到了。</p>

<p class="tip">
为了加速频发查找的效率，此接口是默认自带cache的，如果要禁用cache，可以在工程目录执行`xmake f -c`清除本地cache。
</p>

<p>我们也可以通过<code class="highlighter-rouge">xmake lua lib.detect.find_tool clang</code> 来快速测试。</p>

<h6 id="detectfind_toolname">detect.find_toolname</h6>

<ul>
  <li>查找工具名</li>
</ul>

<p>通过program命令匹配对应的工具名，例如：</p>

<table>
  <thead>
    <tr>
      <th>program</th>
      <th>toolname</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="highlighter-rouge">xcrun -sdk macosx clang</code></td>
      <td>clang</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">/usr/bin/arm-linux-gcc</code></td>
      <td>gcc</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">link.exe -lib</code></td>
      <td>link</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">gcc-5</code></td>
      <td>gcc</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">arm-android-clang++</code></td>
      <td>clangxx</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">pkg-config</code></td>
      <td>pkg_config</td>
    </tr>
  </tbody>
</table>

<p>toolname相比program，更能唯一标示某个工具，也方便查找和加载对应的脚本<code class="highlighter-rouge">find_xxx.lua</code>。</p>

<h6 id="detectfeatures">detect.features</h6>

<ul>
  <li>获取指定工具的所有特性</li>
</ul>

<p>此接口跟<a href="#compiler-features">compiler.features</a>类似，区别就是此接口更加的原始，传入的参数是实际的工具名toolname。</p>

<p>并且此接口不仅能够获取编译器的特性，任何工具的特性都可以获取，因此更加通用。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.features"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">flags</span> <span class="o">=</span> <span class="s2">"-O0"</span><span class="p">,</span> <span class="n">program</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="n">flags</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O0"</span><span class="p">,</span> <span class="s2">"-std=c++11"</span><span class="p">}})</span>
</code></pre>
</div>

<p>通过传入flags，可以改变特性的获取结果，例如一些c++11的特性，默认情况下获取不到，通过启用<code class="highlighter-rouge">-std=c++11</code>后，就可以获取到了。</p>

<p>所有编译器的特性列表，可以见：<a href="#compiler-features">compiler.features</a>。</p>

<h6 id="detecthas_features">detect.has_features</h6>

<ul>
  <li>判断指定特性是否支持</li>
</ul>

<p>此接口跟<a href="#compiler-has_features">compiler.has_features</a>类似，但是更加原始，传入的参数是实际的工具名toolname。</p>

<p>并且此接口不仅能够判断编译器的特性，任何工具的特性都可以判断，因此更加通用。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.has_features"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">has_features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="s2">"cxx_constexpr"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">has_features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"cxx_constexpr"</span><span class="p">,</span> <span class="s2">"c_static_assert"</span><span class="p">},</span> <span class="p">{</span><span class="n">flags</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O0"</span><span class="p">},</span> <span class="n">program</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">features</span> <span class="o">=</span> <span class="n">has_features</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"cxx_constexpr"</span><span class="p">,</span> <span class="s2">"c_static_assert"</span><span class="p">},</span> <span class="p">{</span><span class="n">flags</span> <span class="o">=</span> <span class="s2">"-g"</span><span class="p">})</span>
</code></pre>
</div>

<p>如果指定的特性列表存在，则返回实际支持的特性子列表，如果都不支持，则返回nil，我们也可以通过指定flags去改变特性的获取规则。</p>

<p>所有编译器的特性列表，可以见：<a href="#compiler-features">compiler.features</a>。</p>

<h6 id="detecthas_flags">detect.has_flags</h6>

<ul>
  <li>判断指定参数选项是否支持</li>
</ul>

<p>此接口跟<a href="#compiler-has_flags">compiler.has_flags</a>类似，但是更加原始，传入的参数是实际的工具名toolname。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.has_flags"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_flags</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="s2">"-g"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_flags</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"-g"</span><span class="p">,</span> <span class="s2">"-O0"</span><span class="p">},</span> <span class="p">{</span><span class="n">program</span> <span class="o">=</span> <span class="s2">"xcrun -sdk macosx clang"</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_flags</span><span class="p">(</span><span class="s2">"clang"</span><span class="p">,</span> <span class="s2">"-g -O0"</span><span class="p">,</span> <span class="p">{</span><span class="n">toolkind</span> <span class="o">=</span> <span class="s2">"cxx"</span><span class="p">})</span>
</code></pre>
</div>

<p>如果检测通过，则返回true。</p>

<p>此接口的检测做了一些优化，除了cache机制外，大部分场合下，会去拉取工具的选项列表（<code class="highlighter-rouge">--help</code>）直接判断，如果选项列表里获取不到的话，才会通过尝试运行的方式来检测。</p>

<h6 id="detecthas_cfuncs">detect.has_cfuncs</h6>

<ul>
  <li>判断指定c函数是否存在</li>
</ul>

<p>此接口是<a href="#detect-check_cxsnippets">lib.detect.check_cxsnippets</a>的简化版本，仅用于检测函数。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.has_cfuncs"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_cfuncs</span><span class="p">(</span><span class="s2">"setjmp"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_cfuncs</span><span class="p">({</span><span class="s2">"sigsetjmp((void*)0, 0)"</span><span class="p">,</span> <span class="s2">"setjmp"</span><span class="p">},</span> <span class="p">{</span><span class="n">includes</span> <span class="o">=</span> <span class="s2">"setjmp.h"</span><span class="p">})</span>
</code></pre>
</div>

<p>对于函数的描述规则如下：</p>

<table>
  <thead>
    <tr>
      <th>函数描述</th>
      <th>说明</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="highlighter-rouge">sigsetjmp</code></td>
      <td>纯函数名</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">sigsetjmp((void*)0, 0)</code></td>
      <td>函数调用</td>
    </tr>
    <tr>
      <td><code class="highlighter-rouge">sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}</code></td>
      <td>函数名 + {}块</td>
    </tr>
  </tbody>
</table>

<p>在最后的可选参数中，除了可以指定<code class="highlighter-rouge">includes</code>外，还可以指定其他的一些参数用于控制编译检测的选项条件：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span> <span class="n">verbose</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="n">target</span> <span class="o">=</span> <span class="p">[</span><span class="n">target</span><span class="err">|</span><span class="n">option</span><span class="p">],</span> <span class="n">includes</span> <span class="o">=</span> <span class="o">..</span><span class="p">,</span> <span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="n">linkdirs</span> <span class="o">=</span> <span class="o">..</span><span class="p">,</span> <span class="n">links</span> <span class="o">=</span> <span class="o">..</span><span class="p">,</span> <span class="n">defines</span> <span class="o">=</span> <span class="o">..</span><span class="p">}}</span>
</code></pre>
</div>

<p>其中verbose用于回显检测信息，target用于在检测前追加target中的配置信息, 而config用于自定义配置跟target相关的编译选项。</p>

<h6 id="detecthas_cxxfuncs">detect.has_cxxfuncs</h6>

<ul>
  <li>判断指定c++函数是否存在</li>
</ul>

<p>此接口跟<a href="#detect-has_cfuncs">lib.detect.has_cfuncs</a>类似，请直接参考它的使用说明，唯一区别是这个接口用于检测c++函数。</p>

<h6 id="detecthas_cincludes">detect.has_cincludes</h6>

<ul>
  <li>判断指定c头文件是否存在</li>
</ul>

<p>此接口是<a href="#detect-check_cxsnippets">lib.detect.check_cxsnippets</a>的简化版本，仅用于检测头文件。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.has_cincludes"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_cincludes</span><span class="p">(</span><span class="s2">"stdio.h"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_cincludes</span><span class="p">({</span><span class="s2">"stdio.h"</span><span class="p">,</span> <span class="s2">"stdlib.h"</span><span class="p">},</span> <span class="p">{</span><span class="n">target</span> <span class="o">=</span> <span class="n">target</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_cincludes</span><span class="p">({</span><span class="s2">"stdio.h"</span><span class="p">,</span> <span class="s2">"stdlib.h"</span><span class="p">},</span> <span class="p">{</span><span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="n">defines</span> <span class="o">=</span> <span class="s2">"_GNU_SOURCE=1"</span><span class="p">,</span> <span class="n">languages</span> <span class="o">=</span> <span class="s2">"cxx11"</span><span class="p">}})</span>
</code></pre>
</div>

<h6 id="detecthas_cxxincludes">detect.has_cxxincludes</h6>

<ul>
  <li>判断指定c++头文件是否存在</li>
</ul>

<p>此接口跟<a href="#detect-has_cincludes">lib.detect.has_cincludess</a>类似，请直接参考它的使用说明，唯一区别是这个接口用于检测c++头文件。</p>

<h6 id="detecthas_ctypes">detect.has_ctypes</h6>

<ul>
  <li>判断指定c类型是否存在</li>
</ul>

<p>此接口是<a href="#detect-check_cxsnippets">lib.detect.check_cxsnippets</a>的简化版本，仅用于检测函数。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.has_ctypes"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_ctypes</span><span class="p">(</span><span class="s2">"wchar_t"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_ctypes</span><span class="p">({</span><span class="s2">"char"</span><span class="p">,</span> <span class="s2">"wchar_t"</span><span class="p">},</span> <span class="p">{</span><span class="n">includes</span> <span class="o">=</span> <span class="s2">"stdio.h"</span><span class="p">})</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">has_ctypes</span><span class="p">(</span><span class="s2">"wchar_t"</span><span class="p">,</span> <span class="p">{</span><span class="n">includes</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"stdio.h"</span><span class="p">,</span> <span class="s2">"stdlib.h"</span><span class="p">},</span> <span class="n">config</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"defines = "</span><span class="n">_GNU_SOURCE</span><span class="o">=</span><span class="mi">1</span><span class="s2">", languages = "</span><span class="n">cxx11</span><span class="s2">"}})
</span></code></pre>
</div>

<h6 id="detecthas_cxxtypes">detect.has_cxxtypes</h6>

<ul>
  <li>判断指定c++类型是否存在</li>
</ul>

<p>此接口跟<a href="#detect-has_ctypes">lib.detect.has_ctypess</a>类似，请直接参考它的使用说明，唯一区别是这个接口用于检测c++类型。</p>

<h6 id="detectcheck_cxsnippets">detect.check_cxsnippets</h6>

<ul>
  <li>检测c/c++代码片段是否能够编译通过</li>
</ul>

<p>通用的c/c++代码片段检测接口，通过传入多个代码片段列表，它会自动生成一个编译文件，然后常识对它进行编译，如果编译通过返回true。</p>

<p>对于一些复杂的编译器特性，连<a href="#compiler-has_features">compiler.has_features</a>都无法检测到的时候，可以通过此接口通过尝试编译来检测它。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"lib.detect.check_cxsnippets"</span><span class="p">)</span>

<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">check_cxsnippets</span><span class="p">(</span><span class="s2">"void test() {}"</span><span class="p">)</span>
<span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">check_cxsnippets</span><span class="p">({</span><span class="s2">"void test(){}"</span><span class="p">,</span> <span class="s2">"#define TEST 1"</span><span class="p">},</span> <span class="p">{</span><span class="n">types</span> <span class="o">=</span> <span class="s2">"wchar_t"</span><span class="p">,</span> <span class="n">includes</span> <span class="o">=</span> <span class="s2">"stdio.h"</span><span class="p">})</span>
</code></pre>
</div>

<p>此接口是<a href="#detect-has_cfuncs">detect.has_cfuncs</a>, <a href="#detect-has_cincludes">detect.has_cincludes</a>和<a href="detect-has_ctypes">detect.has_ctypes</a>等接口的通用版本，也更加底层。</p>

<p>因此我们可以用它来检测：types, functions, includes 还有 links，或者是组合起来一起检测。</p>

<p>第一个参数为代码片段列表，一般用于一些自定义特性的检测，如果为空，则可以仅仅检测可选参数中条件，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">ok</span> <span class="o">=</span> <span class="n">check_cxsnippets</span><span class="p">({},</span> <span class="p">{</span><span class="n">types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"wchar_t"</span><span class="p">,</span> <span class="s2">"char*"</span><span class="p">},</span> <span class="n">includes</span> <span class="o">=</span> <span class="s2">"stdio.h"</span><span class="p">,</span> <span class="n">funcs</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"sigsetjmp"</span><span class="p">,</span> <span class="s2">"sigsetjmp((void*)0, 0)"</span><span class="p">}})</span>
</code></pre>
</div>

<p>上面那个调用，会去同时检测types, includes和funcs是否都满足，如果通过返回true。</p>

<p>还有其他一些可选参数：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="p">{</span> <span class="n">verbose</span> <span class="o">=</span> <span class="kc">false</span><span class="p">,</span> <span class="n">target</span> <span class="o">=</span> <span class="p">[</span><span class="n">target</span><span class="err">|</span><span class="n">option</span><span class="p">],</span> <span class="n">sourcekind</span> <span class="o">=</span> <span class="s2">"[cc|cxx]"</span><span class="p">}</span>
</code></pre>
</div>

<p>其中verbose用于回显检测信息，target用于在检测前追加target中的配置信息, sourcekind 用于指定编译器等工具类型，例如传入<code class="highlighter-rouge">cxx</code>强制作为c++代码来检测。</p>

<h5 id="nethttp">net.http</h5>

<p>此模块提供http的各种操作支持，目前提供的接口如下：</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#http-download">http.download</a></td>
      <td>下载http文件</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="httpdownload">http.download</h6>

<ul>
  <li>下载http文件</li>
</ul>

<p>这个接口比较简单，就是单纯的下载文件。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"net.http"</span><span class="p">)</span>

<span class="n">http</span><span class="p">.</span><span class="n">download</span><span class="p">(</span><span class="s2">"http://xmake.io"</span><span class="p">,</span> <span class="s2">"/tmp/index.html"</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="privilegesudo">privilege.sudo</h5>

<p>此接口用于通过<code class="highlighter-rouge">sudo</code>来运行命令，并且提供了平台一致性处理，对于一些需要root权限运行的脚本，可以使用此接口。</p>

<p class="warning">
为了保证安全性，除非必须使用的场合，其他情况下尽量不要使用此接口。
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#sudo-has">sudo.has</a></td>
      <td>判断sudo是否支持</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-run">sudo.run</a></td>
      <td>安静运行程序</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-runv">sudo.runv</a></td>
      <td>安静运行程序，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-exec">sudo.exec</a></td>
      <td>回显运行程序</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-execv">sudo.execv</a></td>
      <td>回显运行程序，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-iorun">sudo.iorun</a></td>
      <td>运行并获取程序输出内容</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#sudo-iorunv">sudo.iorunv</a></td>
      <td>运行并获取程序输出内容，带参数列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="sudohas">sudo.has</h6>

<ul>
  <li>判断sudo是否支持</li>
</ul>

<p>目前仅在<code class="highlighter-rouge">macosx/linux</code>下支持sudo，windows上的管理员权限运行暂时还不支持，因此建议使用前可以通过此接口判断支持情况后，针对性处理。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"privilege.sudo"</span><span class="p">)</span>

<span class="k">if</span> <span class="n">sudo</span><span class="p">.</span><span class="n">has</span><span class="p">()</span> <span class="k">then</span>
    <span class="n">sudo</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"rm /system/file"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<h6 id="sudorun">sudo.run</h6>

<ul>
  <li>安静运行原生shell命令</li>
</ul>

<p>具体用法可参考：<a href="#os-run">os.run</a>。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"privilege.sudo"</span><span class="p">)</span>

<span class="n">sudo</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"rm /system/file"</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="sudorunv">sudo.runv</h6>

<ul>
  <li>安静运行原生shell命令，带参数列表</li>
</ul>

<p>具体用法可参考：<a href="#os-runv">os.runv</a>。</p>

<h6 id="sudoexec">sudo.exec</h6>

<ul>
  <li>回显运行原生shell命令</li>
</ul>

<p>具体用法可参考：<a href="#os-exec">os.exec</a>。</p>

<h6 id="sudoexecv">sudo.execv</h6>

<ul>
  <li>回显运行原生shell命令，带参数列表</li>
</ul>

<p>具体用法可参考：<a href="#os-execv">os.execv</a>。</p>

<h6 id="sudoiorun">sudo.iorun</h6>

<ul>
  <li>安静运行原生shell命令并获取输出内容</li>
</ul>

<p>具体用法可参考：<a href="#os-iorun">os.iorun</a>。</p>

<h6 id="sudoiorunv">sudo.iorunv</h6>

<ul>
  <li>安静运行原生shell命令并获取输出内容，带参数列表</li>
</ul>

<p>具体用法可参考：<a href="#os-iorunv">os.iorunv</a>。</p>

<h5 id="develgit">devel.git</h5>

<p>此接口提供了git各种命令的访问接口，相对于直接调用git命令，此模块提供了更加上层易用的封装接口，并且提供对git的自动检测和跨平台处理。</p>

<p class="tip">
目前windows上，需要手动安装git包后，才能检测到，后续版本会提供自动集成git功能，用户将不用关心如何安装git，就可以直接使用。
</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#git-clone">git.clone</a></td>
      <td>clone代码库</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-pull">git.pull</a></td>
      <td>拉取代码库最新提交</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-clean">git.clean</a></td>
      <td>清理代码库文件</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-checkout">git.checkout</a></td>
      <td>签出指定分支版本</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-refs">git.refs</a></td>
      <td>获取所有引用列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-tags">git.tags</a></td>
      <td>获取所有标记列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
    <tr>
      <td><a href="#git-branches">git.branches</a></td>
      <td>获取所有分支列表</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="gitclone">git.clone</h6>

<ul>
  <li>clone代码库</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git clone</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="n">git</span><span class="p">.</span><span class="n">clone</span><span class="p">(</span><span class="s2">"git@github.com:tboox/xmake.git"</span><span class="p">)</span>
<span class="n">git</span><span class="p">.</span><span class="n">clone</span><span class="p">(</span><span class="s2">"git@github.com:tboox/xmake.git"</span><span class="p">,</span> <span class="p">{</span><span class="n">depth</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">branch</span> <span class="o">=</span> <span class="s2">"master"</span><span class="p">,</span> <span class="n">outputdir</span> <span class="o">=</span> <span class="s2">"/tmp/xmake"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="gitpull">git.pull</h6>

<ul>
  <li>拉取代码库最新提交</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git pull</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="n">git</span><span class="p">.</span><span class="n">pull</span><span class="p">()</span>
<span class="n">git</span><span class="p">.</span><span class="n">pull</span><span class="p">({</span><span class="n">remote</span> <span class="o">=</span> <span class="s2">"origin"</span><span class="p">,</span> <span class="n">tags</span> <span class="o">=</span> <span class="kc">true</span><span class="p">,</span> <span class="n">branch</span> <span class="o">=</span> <span class="s2">"master"</span><span class="p">,</span> <span class="n">repodir</span> <span class="o">=</span> <span class="s2">"/tmp/xmake"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="gitclean">git.clean</h6>

<ul>
  <li>清理代码库文件</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git clean</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="n">git</span><span class="p">.</span><span class="n">clean</span><span class="p">()</span>
<span class="n">git</span><span class="p">.</span><span class="n">clean</span><span class="p">({</span><span class="n">repodir</span> <span class="o">=</span> <span class="s2">"/tmp/xmake"</span><span class="p">,</span> <span class="n">force</span> <span class="o">=</span> <span class="kc">true</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="gitcheckout">git.checkout</h6>

<ul>
  <li>签出指定分支版本</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git checkout</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="n">git</span><span class="p">.</span><span class="n">checkout</span><span class="p">(</span><span class="s2">"master"</span><span class="p">,</span> <span class="p">{</span><span class="n">repodir</span> <span class="o">=</span> <span class="s2">"/tmp/xmake"</span><span class="p">})</span>
<span class="n">git</span><span class="p">.</span><span class="n">checkout</span><span class="p">(</span><span class="s2">"v1.0.1"</span><span class="p">,</span> <span class="p">{</span><span class="n">repodir</span> <span class="o">=</span> <span class="s2">"/tmp/xmake"</span><span class="p">})</span>
</code></pre>
</div>

<h6 id="gitrefs">git.refs</h6>

<ul>
  <li>获取所有引用列表</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git ls-remote --refs</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="kd">local</span> <span class="n">refs</span> <span class="o">=</span> <span class="n">git</span><span class="p">.</span><span class="n">refs</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="gittags">git.tags</h6>

<ul>
  <li>获取所有标记列表</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git ls-remote --tags</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="kd">local</span> <span class="n">tags</span> <span class="o">=</span> <span class="n">git</span><span class="p">.</span><span class="n">tags</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</code></pre>
</div>

<h6 id="gitbranches">git.branches</h6>

<ul>
  <li>获取所有分支列表</li>
</ul>

<p>此接口对应<code class="highlighter-rouge">git ls-remote --heads</code>命令</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"devel.git"</span><span class="p">)</span>
 
<span class="kd">local</span> <span class="n">branches</span> <span class="o">=</span> <span class="n">git</span><span class="p">.</span><span class="n">branches</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</code></pre>
</div>

<h5 id="utilsarchive">utils.archive</h5>

<p>此模块用于压缩和解压缩文件。</p>

<table>
  <thead>
    <tr>
      <th>接口</th>
      <th>描述</th>
      <th>支持版本</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#archive-extract">archive.extract</a></td>
      <td>解压文件</td>
      <td>&gt;= 2.1.5</td>
    </tr>
  </tbody>
</table>

<h6 id="archiveextract">archive.extract</h6>

<ul>
  <li>解压文件</li>
</ul>

<p>支持大部分常用压缩文件的解压，它会自动检测系统提供了哪些解压工具，然后适配到最合适的解压器对指定压缩文件进行解压操作。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"utils.archive"</span><span class="p">)</span>

<span class="n">archive</span><span class="p">.</span><span class="n">extract</span><span class="p">(</span><span class="s2">"/tmp/a.zip"</span><span class="p">,</span> <span class="s2">"/tmp/outputdir"</span><span class="p">)</span>
<span class="n">archive</span><span class="p">.</span><span class="n">extract</span><span class="p">(</span><span class="s2">"/tmp/a.7z"</span><span class="p">,</span> <span class="s2">"/tmp/outputdir"</span><span class="p">)</span>
<span class="n">archive</span><span class="p">.</span><span class="n">extract</span><span class="p">(</span><span class="s2">"/tmp/a.gzip"</span><span class="p">,</span> <span class="s2">"/tmp/outputdir"</span><span class="p">)</span>
<span class="n">archive</span><span class="p">.</span><span class="n">extract</span><span class="p">(</span><span class="s2">"/tmp/a.tar.bz2"</span><span class="p">,</span> <span class="s2">"/tmp/outputdir"</span><span class="p">)</span>
</code></pre>
</div>

        </article>
        <hr>

        <!-- baidu ads -->
        

        
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
                    
                    <h2 id="chinese">中文</h2>
                    <ul>
                    
                    <li class="relatedPost">
                        <a href="/cn/docs/xmake/manual/">接口手册
                        
                        </a>
                    </li>
                    
                    
                
            
        
            
        
            
            
                
            
        
        
            </ul>
        

        
        
            
            
            
                
                    
                        
                        <h2 id="similar_posts">Similar Posts</h2>
                        <ul>
                        
                        <li class="relatedPost">
                            <a href="/2021/12/17/xmake-update-v2.6.2/">Xmake v2.6.2 released, Support building Linux kernel driver module
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/2021/12/03/xmake-update-v2.6.1/">xmake v2.6.1 released, Switch to Lua5.4 runtime, Support Rust and C++ mixed compilation
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/2021/10/30/xmake-update-v2.5.9/">xmake v2.5.9 released, Improve C++20 Modules and support Nim, Keil MDK and Unity Build
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/2021/10/08/xmake-update-v2.5.8/">xmake v2.5.8 is released, Support Pascal/Swig program and Lua53 runtime
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/2021/08/29/xmake-update-v2.5.7/">xmake v2.5.7 released, Use lockfile to freeze package dependencies and Vala/Metal language support
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
            
            
        
            
        
        
            </ul>
        

        <div class="post-recent">
    <div class="pre">

        

        

        
        
        

        

        

        
        
        <p><strong>Prev Post</strong> <a href="/docs/xmake/quickstart/">Quick Start</a></p>
        
    </div>

    <div class="nex">

        

        

        
        
        

        

        

        
        
        <p><strong>Next Post</strong> <a href="/docs/xmake/plugins/">Plugin Development</a></p>
        
    </div>
</div>


        <h2 id="comments">Comments</h2>
        






<div id="gitalk-container"></div>
<link rel="stylesheet" href="/css/gitalk.css">
<script src="/js/gitalk.min.js"></script>

<script>
const gitalk = new Gitalk({
  clientID: '73946dc1d9e2276ad0da',
  clientSecret: '12a3cb94361ba3ebc6ecb68cf80d592bfaa8106d',
  repo: 'tboox.github.io',
  owner: 'waruqi',
  admin: ['waruqi'],
  id: location.pathname,      
  language: 'en',
  distractionFreeMode: false  
})

gitalk.render('gitalk-container')
</script>





    </div>
    <button class="anchor"><i class="fa fa-anchor"></i></button>
    <div class="right">
        <div class="wrap">


            <!-- codefund ads -->
            

            <!-- Content -->
            <div class="side content">
                <div>
                    Content
                </div>
                <ul id="content-side" class="content-ul">
                    <li><a href="#chinese">中文</a></li>
                    <li><a href="#similar_posts">Similar Posts</a></li>
                    <li><a href="#comments">Comments</a></li>
                </ul>
            </div>

            <!-- baidu ads -->
            

            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    Links
                </div>
                <ul class="content-ul">
                  <li><a href="http://github.com/waruqi/tbox">tbox</a></li>
                  <li><a href="http://www.xmake.io">xmake</a></li>
                  <li><a href="https://github.com/waruqi">github</a></li>
                </ul>
            </div> 

            <!-- google ads -->
            

            <!-- baidu ads -->
            

            <!-- chitika ads -->
            
        </div>
    </div>

    <!-- baidu ads -->
    
</div>
<script>
/**
 * target _blank
 */
(function() {
    var aTags = document.querySelectorAll('article a:not([id])')
    for (var i = 0; i < aTags.length; i++) {
        aTags[i].setAttribute('target', '_blank')
    }
}());
</script>
<script src="/js/pageContent.js " charset="utf-8"></script>



    <footer class="site-footer">
    <div class="wrapper">
        <p class="description">
             Copyright (c) 2016-2020 tboox.org 
        </p>
        <p class="contact">
            
            <a href="https://github.com/waruqi" title="GitHub"><i class="fa fa-github" aria-hidden="true"></i></a> 
             
            
            <a href="mailto:waruqi@gmail.com" title="email"><i class="fa fa-envelope-o" aria-hidden="true"></i></a> 
            
            
            <a href="https://twitter.com/waruqi" title="Twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a> 
            
            <a href="/feed.xml" title="feed"><i class="fa fa-feed" aria-hidden="true"></i></a> 
        </p>
        <p class="power">
            <span>
                Site powered by <a href="https://jekyllrb.com/">Jekyll</a> & <a href="https://github.com/Gaohaoyang">HyG</a> & <a href="https://pages.github.com/">Github Pages</a>.
            </span>
        </p>
    </div>
</footer>

    <div class="back-to-top">
    <a href="#top" class="scroll">
        <i class="fa fa-arrow-up" aria-hidden="true"></i>
    </a>
</div>

    <script src=" /js/main.js " charset="utf-8"></script>
    <script src=" /js/scroll.min.js " charset="utf-8"></script>
  </body>

</html>
